一、环境要求
** php > 7.1.3
** Apache 开重写模块
二、laravel框架搭建
1 安装laravel(先安装好composer)
composer create-project --prefer-dist laravel/laravel live "5.6.*"
2.1 安装dingo
修改composer.json
文件,在 require
中添加
"dingo/api": "2.0.0-alpha1"
然后使用命令行,进入项目目录,执行
composer update
来更新、安装新包
接下来就publish
php artisan vendor:publish --provider="Dingo\Api\Provider\LaravelServiceProvider"
2.2 创建Api
修改routes/api.php
<?php
$api = app("Dingo\Api\Routing\Router");
$api->version('v1', function ($api) {
$api->group(["namespace" => "App\Http\Controllers\Api",'middleware'=>'auth:api'], function ($api) {
//之后在这里写api
$api->post('decode', 'AccountController@decode');
});
$api->group(["namespace" => "App\Http\Controllers\Api"], function ($api) {
//之后在这里写api
$api->post('login', 'AccountController@login');
});
});
2.3 创建BaseController
<?php
namespace App\Http\Controllers\Api;
use Illuminate\Http\Request;
use Dingo\Api\Routing\Helpers;
use App\Http\Controllers\Controller;
class BaseController extends Controller
{
//
use Helpers;
/****
* BaseController constructor.
*/
public function __construct()
{
}
}
3.1 安装jwt
修改composer.json文件,在 require中添加
"tymon/jwt-auth": "^1.0.0-rc.1"
然后使用命令行,进入项目目录,执行
composer update
接下来就publish
php artisan vendor:publish --provider="Tymon\JWTAuth\Providers\LaravelServiceProvider"
3.2 生成秘钥
php artisan jwt:secret
3.3 修改Account模型(我的路径为app\Models\Account.php)
<?php
namespace App\Models;
use Tymon\JWTAuth\Contracts\JWTSubject;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authuser;
class Account extends Authuser implements JWTSubject
{
use Notifiable;
protected $hidden = ['password'];
// Rest omitted for brevity
/**
* Get the identifier that will be stored in the subject claim of the JWT.
*
* @return mixed
*/
public function getJWTIdentifier()
{
return $this->getKey(); /*自己可以定义的生成token的参数,我用的是将主键加密*/
}
/**
* Return a key value array, containing any custom claims to be added to the JWT.
*
* @return array
*/
public function getJWTCustomClaims()
{
return [];
}
//定义表
protected $table = "accounts";
//定义主键
protected $primaryKey = "id";
}
3.4 配置Auth guard
修改config/auth.php
修改defaults的guards为
'guard' => 'api',
在guards
中添加
'api' => [
'driver' => 'jwt',
'provider' => 'users',
],
在provides
中,修改users为
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\Models\Account::class, //自己定义的模型
],
3.5 创建AccountController
(我的路径为app\Http\Controllers\Api\AccountController.php
)
<?php
namespace App\Http\Controllers\Api;
use App\Exceptions\BaseException;
use App\Models\Account;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Illuminate\Http\Resources\Json\JsonResource;
use Illuminate\Support\Facades\Auth;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\Translation\Tests\Dumper\JsonFileDumperTest;
use Tymon\JWTAuth\JWTAuth;
class AccountController extends BaseController
{
protected $jwt;
public function __construct(JWTAuth $jwt)
{
$this->jwt = $jwt;
}
public function login(Request $request)
{
$this->validate($request, [
'email' => 'required|email|max:255',
'password' => 'required',
]);
try {
//验证用户是否存在,存在则颁发token,不存在,则不颁发token。
if (! $token = $this->jwt->attempt($request->only('email', 'password'))) {
return response()->json(['user_not_found'], 404);
}
} catch (\Tymon\JWTAuth\Exceptions\TokenExpiredException $e) {
return response()->json(['token_expired'], 500);
} catch (\Tymon\JWTAuth\Exceptions\TokenInvalidException $e) {
return response()->json(['token_invalid'], 500);
} catch (\Tymon\JWTAuth\Exceptions\JWTException $e) {
return response()->json(['token_absent' => $e->getMessage()], 500);
}
return JsonResponse::create([
'success'=>'200',
'msg'=>'ok',
'data'=>[
'user'=>Auth::user(),
'token'=>$token
]
]);
}
/*测试方法*/
public function decode(Request $request){
throw new BaseException('订单',200);
}
}
至此,基本搭建完了.剩下的我们把dingoh和jwt联系起来 :
首先,在app\Providers\AppServiceProvider.php
中的boot
方法里面添加dingo添加jwt扩展
public function boot(){
//驱动
app('Dingo\Api\Auth\Auth')->extend('jwt', function ($app) {
return new \Dingo\Api\Auth\Provider\JWT($app['Tymon\JWTAuth\JWTAuth']);
});
}
然后在config\api.php
找到’auth’=>[],修改如下:
'auth' => [
'jwt' => 'Dingo\Api\Auth\Provider\JWT',
],
config\app.php
中providers
添加:
Dingo\Api\Provider\LaravelServiceProvider::class,
Tymon\JWTAuth\Providers\LaravelServiceProvider::class,
然后:
config\jwt.php 这个文件在上面执行命令的时候会自动从vendor\tymon\jwt-auth\config\config.php
复制过去,如果没有这个文件请手动执行
文件里面注意这三个地方(这是正确的写法
):
'jwt' => Tymon\JWTAuth\Providers\JWT\Lcobucci::class,
'auth' => Tymon\JWTAuth\Providers\Auth\Illuminate::class,
'storage' => Tymon\JWTAuth\Providers\Storage\Illuminate::class,
最后在.env 中添加
API_PREFIX=api
API_STANDARDS_TREE=vnd
API_VERSION=v1
API_DEBUG=false
用户登录成功之后,下一步就是发送一个包含token的请求来获取用户信息。
要通过http发送一个需要认证通过的请求,需要设置Authorization头:
Authorization: Bearer+空格+token
下面我们使用postman
做接口测试:
地址: gems.com/api/login
生成token
,地址不走验证(此接口不走中间件)
地址: gems.com/api/decode
前端拿着token
通过header
传来进行验证(此接口走中间件)
注意:
如果你本地是好的搬到服务器上就不可以了
Apache似乎会摒弃Authorization头,要修复这一问题你可以添加如下代码到Apache配置文件:
RewriteEngine On
RewriteCond %{HTTP:Authorization} ^(.*)
RewriteRule .* - [e=HTTP_AUTHORIZATION:%1]
或者将token信息包含到URL中:
http://api.mysite.com/me?token={yourtokenhere}