之前我使用了Laravel的内置api令牌身份验证,但我想为不同的客户提供多个api令牌,并且在Laravel 7.x中,我尝试迁移到Laravel Sanctum。
API似乎可以正常验证用户,但当我尝试用 Auth::user();
获取用户数据时,它返回null,而 Auth::guard('api')->user();
也返回null。
我应该使用什么作为Auth guard?或者基于提供的令牌获取用户数据的方法是否正确?
非常感谢....
之前我使用了Laravel的内置api令牌身份验证,但我想为不同的客户提供多个api令牌,并且在Laravel 7.x中,我尝试迁移到Laravel Sanctum。
API似乎可以正常验证用户,但当我尝试用 Auth::user();
获取用户数据时,它返回null,而 Auth::guard('api')->user();
也返回null。
我应该使用什么作为Auth guard?或者基于提供的令牌获取用户数据的方法是否正确?
非常感谢....
auth('sanctum')->user()->id
auth('sanctum')->check()
首先,通过圣所认证中间件进行路由。
Route::get('/somepage', 'SomeController@MyMethod')->middleware('auth:sanctum');
然后,获取用户。
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class AuthController extends Controller
{
public function MyMethod(Request $request) {
return $request->user();
}
}
auth()->user()
是一个全局帮助函数,Auth::user()
是一个支持门面模式,而 $request->user()
使用 http。你可以使用其中任何一个。
为了进行快速测试,请尝试:
Route::get('/test', function() {
return auth()->user();
})->middleware('auth:sanctum');
请确保将您的令牌作为标题发送,例如:
Authorization: Bearer UserTokenHere
auth:sanctum
中间件,否则它会返回 null。 - Liga最简单的方法是使用auth
助手,例如:
$user = auth('sanctum')->user();
或者您可以通过请求对象获取它
//SomeController.php
public function exampleMethod(Request $request)
{
$user = $request->user();
}
通过 sanctum token 字符串获取用户,例如:
2|bTNlKViqCkCsOJOXWbtNASDKF7SyHwzHOPLNH
代码就像这样
use Laravel\Sanctum\PersonalAccessToken;
//...
$token = PersonalAccessToken::findToken($sactumToken);
$user = $token->tokenable;
注意:传递令牌的最常见方式是通过带有Bearer的授权头。
在 Authorization 标头中发送令牌,下面的代码将返回授权用户。
Route::middleware('auth:sanctum')->group(function () {
Route::get('/profile/me', function (Request $request) {
return $request->user();
});
});
在Restful API中,建议您发送Accept标头以便在验证中间件中进行检查,如果未经过身份验证,则重定向。对于Restful API,默认情况下,如果用户未经过身份验证,则会将其重定向到登录表单(如果有的话)。
namespace App\Http\Middleware;
protected function redirectTo($request)
{
if (!$request->expectsJson()) {
return route('login');
}
}
public function login(Request $request)
{
if(Auth::attempt($credentials))
{
$userid = auth()->user()->id;
}
}
private $status_code= 200; // successfully
public function register(Request $request)
{
// $validator = $this->validator($request->all())->validate();
$validator = Validator::make($request->all(),
[
'name' => ['required', 'string', 'max:255'],
'email' => ['required', 'string', 'email', 'max:255'], // , 'unique:users'
'password' => ['required', 'string', 'min:4'],
]
);
if($validator->fails()) {
return response()->json(["status" => "failed", "message" => "Please Input Valid Data", "errors" => $validator->errors()]);
}
$user_status = User::where("email", $request->email)->first();
if(!is_null($user_status)) {
return response()->json(["status" => "failed", "success" => false, "message" => "Whoops! email already registered"]);
}
$user = $this->create($request->all());
if(!is_null($user)) {
$this->guard()->login($user);
return response()->json(["status" => $this->status_code, "success" => true, "message" => "Registration completed successfully", "data" => $user]);
}else {
return response()->json(["status" => "failed", "success" => false, "message" => "Failed to register"]);
}
}
/**
* Get a validator for an incoming registration request.
*
* @param array $data
* @return \Illuminate\Contracts\Validation\Validator
*/
protected function validator(array $data)
{
return Validator::make($data, [
'name' => ['required', 'string', 'max:255'],
'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
'password' => ['required', 'string', 'min:4'],
]);
}
/**
* Create a new user instance after a valid registration.
* @author Mohammad Ali Abdullah ..
* @param array $data
* @return \App\User
*/
protected function create(array $data)
{
return User::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => Hash::make($data['password']),
]);
}
protected function guard()
{
return Auth::guard();
}
/**
* method public
* @author Mohammad Ali Abdullah
* @date 01-01-2021.
*/
public function login(Request $request)
{
$validator = Validator::make($request->all(),
[
"email" => "required|email",
"password" => "required"
]
);
// check validation email and password ..
if($validator->fails()) {
return response()->json(["status" => "failed", "validation_error" => $validator->errors()]);
}
// check user email validation ..
$email_status = User::where("email", $request->email)->first();
if(!is_null($email_status)) {
// check user password validation ..
// ---- first try -----
// $password_status = User::where("email", $request->email)->where("password", Hash::check($request->password))->first();
// if password is correct ..
// ---- first try -----
// if(!is_null($password_status)) {
if(Hash::check($request->password, $email_status->password)) {
$credentials = $request->only('email', 'password');
if (Auth::attempt($credentials)) {
// Authentication passed ..
$authuser = auth()->user();
return response()->json(["status" => $this->status_code, "success" => true, "message" => "You have logged in successfully", "data" => $authuser]);
}
}else {
return response()->json(["status" => "failed", "success" => false, "message" => "Unable to login. Incorrect password."]);
}
}else{
return response()->json(["status" => "failed", "success" => false, "message" => "Email doesnt exist."]);
}
}
public function logout()
{
Auth::logout();
return response()->json(['message' => 'Logged Out'], 200);
}
我看到还没有被接受的答案。我刚遇到了我的 sanctum auth 无法工作的问题。auth() 助手始终返回 null。
为了解决这个问题,我在 api key 下的 kernel.php 中删除了注释。这是关于这个类的 \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class
。这是因为默认情况下它被注释掉了。
'api' => [
\Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
'throttle:api',
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
之后,我通过auth()助手访问了User对象。
namespace App\Http\Middleware;
use Illuminate\Http\Request;
class PromoteSanctumUser
{
/**
* @param Request $request
* @param \Closure $next
*/
public function handle(Request $request, \Closure $next)
{
$sanctumUser = auth('sanctum')->user();
if ($sanctumUser) {
$request->setUserResolver(function() use ($sanctumUser) {
return $sanctumUser;
});
}
return $next($request);
}
}
@parsa-samandizadeh
的解决方案,或者按照以下链接中描述的方式使用可选的 Sanctum Auth 中间件:https://laracasts.com/discuss/channels/laravel/laravel-sanctum-optional-auth-on-route?page=1&replyId=680807 - armezit