我之前使用 Laravel 的内置 api 令牌身份验证,但我想为不同的客户端提供多个 api 令牌,并且在 Laravel 7.x 中,我正在尝试迁移到 Laravel Sanctum。
API 似乎可以毫无问题地验证用户身份,但是当我尝试使用
Auth::user();
获取用户数据时,它返回 null。另外 Auth::guard('api')->user();
也返回 null。
我应该使用什么作为身份验证守卫?还是根据提供的令牌获取用户数据的正确方法?
非常感谢....
auth('sanctum')->user()->id
auth('sanctum')->check()
首先,通过 sainttum auth 中间件进行路由。
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
在授权标头中发送令牌,下面的代码返回身份验证用户。
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');
}
}
最简单的方法是使用
auth
帮助器,例如
$user = auth('sanctum')->user();
或者可以通过请求对象获取
//SomeController.php
public function exampleMethod(Request $request)
{
$user = $request->user();
}
通过 sactum 令牌字符串获取用户,例如
2|bTNlKViqCkCsOJOXWbtNASDKF7SyHwzHOPLNH
代码就像
use Laravel\Sanctum\PersonalAccessToken;
//...
$token = PersonalAccessToken::findToken($sactumToken);
$user = $token->tokenable;
注意:传递令牌的最方式是通过持有者的授权标头
当您登录用户时,在您的登录功能中使用类似这样的内容
public function login(Request $request)
{
if(Auth::attempt($credentials))
{
$userid = auth()->user()->id;
}
}
然后将此用户 ID 发送给客户端,并让它以安全的方式存储在客户端。然后,对于每个请求,您都可以使用此用户 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);
}
我看到还没有答案被接受。我只是遇到了我的圣穴身份验证不起作用的问题。 auth() 帮助器总是返回 null。
为了解决这个问题,我删除了 kernel.php 中 api key 下的注释。这是关于这门课的
\Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class
。这是因为它默认被注释掉了。
'api' => [
\Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
'throttle:api',
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
之后我可以使用 auth() 帮助器访问 User 对象。
我使用控制器的 __constructor() 函数来设置受保护的变量,然后可以在整个控制器中访问用户对象。
/**
* Authenticated user object
*
* @var \Illuminate\Contracts\Auth\Authenticatable|null
*/
protected $user;
/**
* Create a new controller instance.
*
* @return void
*/
public function __construct()
{
$this->middleware(function ($request, $next) {
$this->user = Auth::user();
return $next($request);
});
}
就像魅力一样。
确保 sainttum 中间件在 api 中
我在同一条船上;迁移到 Sanctum 并想知道为什么我所有的 $request->user() 都是空的。对我来说,解决方案是将一些中间件扔到堆栈上以修改请求的 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);
}
}