![](/img/trans.png)
[英]Check if Laravel sanctum token is valid in Nextjs middelware to protect route
[英]use laravel + vue sanctum to protect Route
我正在使用 laravel + vue sanctum,我安装了 sanctum,我尝试隐藏非注册用户的文章并仅向已登录的用户显示它们,但在任何一种情况下文章都不会出现,并且出现此消息在控制台中:
app.js:197 GET http://localhost:8000/api/articles/ 401 (Unauthorized)
app.js:607 Uncaught (in promise) Error: Request failed with status code 401
at createError (app.js:607)
at settle (app.js:878)
at XMLHttpRequest.handleLoad (app.js:82)
我的 api.php 文件是:
Route::middleware('auth:sanctum')->get('/user', function (Request $request) {
return $request->user();
});
Route::group(['middleware' => ['auth:sanctum']], function () {
Route::resource('articles', ArticleController::class);
});
我的登录文件是:
<template>
<div>
<div class="container">
<div class="row d-flex justify-content-center">
<div class="col-6">
<form class="form-signin">
<h1 class="h3 mb-3 font-weight-normal">Please sign in</h1>
<label for="inputEmail" class="sr-only">Email address</label>
<span class="text-danger" v-if="errors.email">{{errors.email[0]}}</span>
<input type="email" id="inputEmail" class="form-control" placeholder="Email address" required autofocus v-model="form.email">
<label for="inputPassword" class="sr-only">Password</label>
<span class="text-danger" v-if="errors.password">{{errors.password[0]}}</span>
<input type="password" id="inputPassword" class="form-control" placeholder="Password" required v-model="form.password">
<div class="checkbox mb-3">
<label>
<input type="checkbox" value="remember-me"> Remember me
</label>
</div>
<button @click.prevent="loginUser" class="btn btn-lg btn-primary btn-block" type="submit">Sign in</button>
<p class="mt-5 mb-3 text-muted">© 2017-2018</p>
</form>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
data(){
return{
form:{
email: '',
password: '',
device_name: 'test'
},
errors: []
}
},
methods:{
loginUser(){
axios.post('/api/login', this.form).then(() =>{
this.$router.push({ name: 'MainPage' })
}).catch((error) =>{
this.errors = error.response.data.errors;
})
}
}
}
</script>
我的登录 controller 是:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
use Illuminate\Validation\ValidationException;
use Illuminate\Support\Facades\Validator;
use App\Models\User;
class LoginController extends Controller
{
public function login(Request $request)
{
$request->validate([
'email' => ['required', 'email'],
'password' => ['required']
]);
if (Auth::attempt($request->only('email', 'password'))){
return response()->json(Auth::user(), 200);
}
throw ValidationException::withMessages([
'email' =>['The provided credentials are incorect.']
]);
// $request->validate([
// 'email' => 'required|email',
// 'password' => 'required',
// 'device_name' => 'required',
// ]);
$user = User::where('email', $request->email)->first();
// if (! $user || ! Hash::check($request->password, $user->password)) {
// throw ValidationException::withMessages([
// 'email' => ['The provided credentials are incorrect.'],
// ]);
// }
// return $user->createToken($request->device_name)->plainTextToken;
return response()->json(['msg' => 'register done']);
}
}
如果你打算使用 sanctum 来验证你的应用程序,你需要
axios.get('/sanctum/csrf-cookie').then(response => {
// Login...
});
在您的情况下,我认为您缺少 csrf,并确保您在同一个域下。
在你的情况下:
loginUser(){
axios.get('/sanctum/csrf-cookie').then(response => {
axios.post('/api/login', this.form).then(() =>{
this.$router.push({ name: 'MainPage' })
}).catch((error) =>{
this.errors = error.response.data.errors;
})
})
}
在这里查看我的 repo 以获得工作参考laravel-vue-sanctum-spa 样板
查看官方文档sanctum docs
就我个人而言,我会在文章中添加一个属性,例如 public。
由于公共用户未登录,因此为公共用户创建单独的路由。 由于您现在使用的方法需要经过身份验证的用户。
public function unauthorizedIndex()
{
return Article::where('public', true)->get()
}
我个人认为您仍然需要访问令牌(不记名令牌)并使用 postman 之类的应用程序首先测试 API。
class LoginController extends Controller
{
use ApiResponser;
public function __invoke(Request $request)
{
// attempting login
if(!auth()->attempt($request->only('email', 'password'))) {
return $this->error(401, 'Credentials not match' );
}
// Delete old tokens
auth()->user()->tokens()->delete();
// Succesfull login and new token created.
return $this->success([
'token' => auth()->user()->createToken('API Token', auth()->user()->abilities())->plainTextToken
]);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.