gpt4 book ai didi

php - 如何使用Laravel实现微服务和API网关之间的认证和授权

转载 作者:行者123 更新时间:2023-12-03 08:05:16 28 4
gpt4 key购买 nike

我正在尝试在我的微服务和 API 网关之间实现用户的身份验证和授权。我现在拥有的:

  1. API 网关,可以向任何微服务发出请求。
  2. 用户微服务 - 我在其中存储所有用户。 laravel/passport 实现了此微服务中的用户身份验证。正常工作,登录路由返回 token ,我使用该 token 在微服务中对用户进行身份验证。
  3. 其他 5 个微服务无需任何身份验证或授权。

问题是:使用微服务进行身份验证和授权的正确方法是什么?我知道我应该在我的 API 网关 中对用户进行身份验证,并且授权将在微服务内部进行。但是,如果其他微服务对用户一无所知,如何进行授权呢?我计划以某种方式使用 JWT token 以及有关用户角色的信息,但尚未找到如何将该信息放入 token 中

最佳答案

我将尝试用 API 的基本示例进行解释。

假设您当前有 3 个微服务:

  1. 用户
  2. 帖子
  3. 核心

我假设您使用 httpOnly cookie 来存储用户 token 。

在核心微服务中,我有这个路由结构:

Route::prefix('core')->group(function () {
Route::post('register', [AuthController::class, 'register']);
Route::post('login', [AuthController::class, 'login']);

Route::middleware('scope.trader')->group(function () {
Route::get('user', [AuthController::class, 'user']);

});
});

现在我想登录,我应该发送 API 请求,并且我应该想出一个在需要时发送 token 的解决方案。

  1. 登录(这是您获取 token 的地方)和注册不需要 token
  2. 用户需要 token (这是您要求解决方案的地方)

因此,除了获得结果之外,我还应该为用户创建一项服务,以下是我的做法:

UserService :
class UserService extends ApiService
{
public function __construct()
{
// Get User Endpoint Microservice API URL
$this->endpoint = env('USERS_MS') . '/api';
}
}
ApiService :
abstract class ApiService
{
protected string $endpoint;

public function request($method, $path, $data = [])
{
$response = $this->getRequest($method, $path, $data);

if ($response->ok()) {return $response->json();};

throw new HttpException($response->status(), $response->body());
}

public function getRequest($method, $path, $data = [])
{
return \Http::acceptJson()->withHeaders([
'Authorization' => 'Bearer ' . request()->cookie('token')
])->$method("{$this->endpoint}/{$path}", $data);
}

public function post($path, $data)
{
return $this->request('post', $path, $data);
}

public function get($path)
{
return $this->request('get', $path);
}

public function put($path, $data)
{
return $this->request('put', $path, $data);
}

public function delete($path)
{
return $this->request('delete', $path);
}
}

如果您想知道这个 UserService 来自哪里,那么我应该说,我已经创建了一个包以在其他微服务中使用它,因此您可以执行相同的操作或只是创建一个服务并在您的微服务等中使用它。

关于 ApiService 的一切都很明显,但我会尝试解释其基础。

  1. 任何时候我们想要进行API调用,我们都可以简单地调用此类中的允许的方法,然后我们的方法将调用请求,传递公共(public)参数,并且最终使用这些参数来执行 API 调用。
  2. getRequest 方法,正在执行调用并从 httpOnly cookie 获取存储的 token ,并将其作为 Authorization header 发送到目标端点,最终它将返回从目标获得的任何内容。

所以如果我们想使用它,我们可以在 Controller 中简单地这样做:

class AuthController extends Controller
{
// use Services\UserService;
public UserService $userService;

/**
* @param UserService $userService
*/
public function __construct(UserService $userService)
{
$this->userService = $userService;
}

public function register(RegisterRequest $request)
{
$data = $request->only('name', 'email', 'password') + ['additional_fileds' => 0 ];
// additional fields can be used for something except from request and
// optional, like is it admin or user or etc.

// call the post method, pass the endpoint url(`register`), pass $data
$user = $this->userService->post('register', $data);
// get data from target endpoint
// and ...
return response($user, Response::HTTP_CREATED);
}

public function login(Request $request)
{
// same thing here again, but this time i passed scope to help me
// get the specific user scope
$data = $request->only('email', 'password') + ['scope' => 'writer'];

$response = $this->userService->post('login', $data);
// as you can see when user do success login, we will get token,
// which i got that token using Passport and set it to $cookie
$cookie = cookie('token', $response['token'], 60 * 24); // 1 day

// then will set a new httpOnly token on response.
return response([
'message' => 'success'
])->withCookie($cookie);
}

public function user(Request $request)
{
// Here, base on userService as you saw, we passed token in all requests
// which if token exist, we get the result, since we're expecting
// token to send back the user informations.

$user = $this->userService->get('user');

// get posts belong to authenticated user
$posts = Post::where('user_id', $user['id'])->get();

$user['posts'] = $posts;

return $user;
}
}

现在,用户微服务怎么样?好吧,这里一切都很清楚,它应该像一个基本的应用程序一样工作。

路线如下:

Route::post('register', [AuthController::class, 'register']);
Route::post('login', [AuthController::class, 'login']);

Route::middleware(['bunch','of', 'middlewares'])->group( function (){
Route::get('user', [AuthController::class, 'user']);
});

在 Controller 中:

class AuthController extends Controller
{
public function register(Request $request)
{
$user = User::create(
$request->only('first_name', 'email', 'additional_field')
+ ['password' => \Hash::make($request->input('password'))]
);

return response($user, Response::HTTP_CREATED);
}


public function login(Request $request)
{
if (!\Auth::attempt($request->only('email', 'password'))) {
return response([
'error' => 'user or pass is wrong or whatever.'
], Response::HTTP_UNAUTHORIZED);
}

$user = \Auth::user();

$jwt = $user->createToken('token', [$request->input('here you can pass the required scope like trader as i expalined in top')])->plainTextToken;

return compact('token');
}

public function user(Request $request)
{
return $request->user();
}
}

这是完整的示例,您可以在其他微服务上使用核心微服务方法来获取与经过身份验证的用户相关的信息,正如您所看到的,所有内容都将通过这些进行身份验证从 core 到其他微服务的请求

关于php - 如何使用Laravel实现微服务和API网关之间的认证和授权,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72575915/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com