全手打,给自己加深印象,用到的朋友点个赞支持下
1.安装配置 jwt
composer require dingo/api:1.0.x@dev
a.引入成功后,在 config/app.php 的 providers 中配置 provider
/*
* Package Service Providers...
*/
Tymon\JWTAuth\Providers\LaravelServiceProvider::class,
b. 执行 php artisan 命令 生成 config/jwt.php 文件
// app/config 文件夹中生成 jwt 配置文件---> jwt.php
php artisan vendor:publish --provider="Tymon\JWTAuth\Providers\LaravelServiceProvider"
c.生成 jwt secret,后续验证 token 会使用
// 在 .env 文件中生成
// JWT_SECRET=Goqosxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
php artisan jwt:secret
d.接下来需要修改 config/auth.php ,defaults 中 guard 改成你的默认 guard,我这里是 admin,因为我这里是做后台的验证,
所以我添加了 admin,并且指定 driver->jwt,provider 下方自己定义的 model
e.最后修改 admin.php model 文件
<?php
namespace Blog\Admin\Models;
use Tymon\JWTAuth\Contracts\JWTSubject;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
class Admin extends Authenticatable implements JWTSubject
{
protected $table = "admin";
protected $fillable = [
'id',
'username',
'password',
];
public function getJWTIdentifier()
{
// TODO: Implement getJWTIdentifier() method.
return $this->getKey();
}
public function getJWTCustomClaims()
{
// TODO: Implement getJWTCustomClaims() method.
return [];
}
}
至此,JWT 安装配置完毕
2.安装配置 Dingo
composer require dingo/api
a.引入成功后,在 config/app.php 的 providers 中配置 provider
/*
* Package Service Providers...
*/
Dingo\Api\Provider\LaravelServiceProvider::class,
Tymon\JWTAuth\Providers\LaravelServiceProvider::class,
b.执行 php artisan 命令 生成 config/api.php 文件
// 在 app/config 文件夹中生成 dingo 配置文件---> api.php
php artisan vendor:publish --provider="Dingo\Api\Provider\LaravelServiceProvider"
c.配置 .env 文件
# Dingo Api config
API_STANDARDS_TREE=vnd // 环境
API_SUBTYPE=blog // 项目名称
API_PREFIX=/ // 前缀
API_DOMAIN=www.blog-api.com //子域名 (前缀和子域名只能存在一个)
API_CONDITIONAL_REQUEST=false // 带条件的请求
API_STRICT=false // 严格模式
API_DEBUG=true // 调试模式
API_DEFAULT_FORMAT=json // 响应格式
API_VERSION=v1 // 版本
d.新建 Admin 文件夹,编写 router,指定 version 为 .env 下 API_VERSION 配置的 v1
e.新建 & 编辑 Admin/AuthController.php ,除了 login 和 register,其余都需要用到 refresh 中间件
<?php
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use Dingo\Api\Contract\Http\Validator;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Blog\Admin\Models\Admin;
class AuthController extends Controller
{
// 查看 config/auth.php 的 guards 设置项,我 auth 中配置的 driver->jwt 为 admin
protected $guard = 'admin';
/**
* Create a new AuthController instance.
* @return void
*/
public function __construct()
{
$this->middleware('refresh', [
'except' => [
'login',
'register',
],
]);
}
public function register(Request $request)
{
$rules = [
'name' => ['required'],
'email' => ['required'],
'password' => [
'required',
'min:6',
'max:255',
],
];
$payload = $request->only('name', 'email', 'password');
$validator = Validator::make($payload, $rules);
// 验证格式
if ($validator->fails()) {
return $this->response->array(['error' => $validator->errors()]);
}
// 创建用户
$result = Admin::create([
'name' => $payload['name'],
'email' => $payload['email'],
'password' => bcrypt($payload['password']),
]);
if (!$result) {
return $this->response->array(['error' => '创建用户失败']);
}
return $this->response->array(['success' => '创建用户成功']);
}
/**
* Get a JWT token via given credentials.
* @param \Illuminate\Http\Request $request
* @return JsonResponse
*/
public function login(Request $request)
{
$credentials = $request->only('email', 'password');
// $pwd = bcrypt($credentials['password']);
if ($token = $this->guard()->attempt($credentials)) {
return $this->respondWithToken($token);
}
return $this->response->errorUnauthorized('登录失败');
}
/**
* Get the authenticated User
* @return \Dingo\Api\Http\Response
*/
public function getAdminWithMe()
{
return $this->response->array($this->guard()->user());
}
/**
* Log the user out (Invalidate the token)
* @return JsonResponse
*/
public function logout()
{
$this->guard()->logout();
return $this->response->array(['message' => '退出成功']);
}
/**
* Refresh a token.
* @return JsonResponse
*/
public function refresh()
{
return $this->respondWithToken($this->guard()->refresh());
}
/**
* Get the token array structure.
* @param string $token
* @return JsonResponse
*/
protected function respondWithToken($token)
{
return response()->json([
'access_token' => $token,
'token_type' => 'bearer',
'expires_in' => $this->guard()->factory()->getTTL() * 60,
]);
}
/**
* Get the guard to be used during authentication.
* @return \Illuminate\Contracts\Auth\Guard
*/
public function guard()
{
return Auth::guard($this->guard);
}
}
f.refresh 中间件(来源:https://www.jianshu.com/p/9e95a5f8ac4a)
<?php
/**
* Created by PhpStorm.
* User: OrangeSix
* Date: 2021/1/18
* Time: 3:46 下午
*/
namespace App\Http\Middleware;
use Closure;
use Tymon\JWTAuth\Exceptions\JWTException;
use Tymon\JWTAuth\Http\Middleware\BaseMiddleware;
use Tymon\JWTAuth\Exceptions\TokenExpiredException;
use Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException;
class RefreshToken extends BaseMiddleware
{
/**
* @param $request
* @param Closure $next
* @return \Illuminate\Http\JsonResponse|\Illuminate\Http\Response|mixed
* @throws JWTException
* @author: zhaogx
*/
public function handle($request, Closure $next)
{
// 检查此次请求中是否带有 token,如果没有则抛出异常。
$this->checkForToken($request);
// 使用 try 包裹,以捕捉 token 过期所抛出的 TokenExpiredException 异常
try {
// 检测用户的登录状态,如果正常则通过
if ($this->auth->parseToken()
->authenticate()) {
return $next($request);
}
throw new UnauthorizedHttpException('jwt-auth', '未登录');
} catch (TokenExpiredException $exception) {
// 此处捕获到了 token 过期所抛出的 TokenExpiredException 异常,我们在这里需要做的是刷新该用户的 token 并将它添加到响应头中
try {
// 刷新用户的 token
$token = $this->auth->refresh();
// 使用一次性登录以保证此次请求的成功
\Auth::guard('api')
->onceUsingId($this->auth->manager()
->getPayloadFactory()
->buildClaimsCollection()
->toPlainArray()['sub']);
} catch (JWTException $exception) {
// 如果捕获到此异常,即代表 refresh 也过期了,用户无法刷新令牌,需要重新登录。
throw new UnauthorizedHttpException('jwt-auth', $exception->getMessage());
}
}
return $next($request)->withHeaders([
'Authorization' => 'Bearer ' . $token,
]);
}
}
3.修改使用 router + middleware
至此结束,有问题欢迎留言。