在 lumen 中使用 jwt(译)
如何在 lumen 中使用 jwt (json web token)
##安装 jwt
在你的项目根目录执行下面的命令1
composer require tymon/jwt-auth
然后我们必须在 Provider 中添加 JWTAuthServiceProvider。 在 Laravel 中有一个名为 config 的文件夹,其中有一个配置文件 app.php,一般都在这个文件中添加 Service Provider,但是在 lumen 中有一些不同。
打开 bootstrap/app.php 文件,找到 Register Service Provider。在这里添加 JWTAuthServiceProvider。
重要提示:如果此时使用 php artisan 命令,你会得到一个config_path 不存在的错误。
改进 lumen
Lumen 默认是没有 config_path 功能的,因为 Lumen 为了文件简洁,将所有配置选项存储在 .env 中,Lumen 中也没有 config 这个文件夹。
这个问题可以很容易的解决掉,手动创建一个 config_path 功能,在 app 目录下创建一个文件 helpers.php。你可以找到这个功能在 GitHub。
1 |
|
现在我们必须让 composer 自动加载这个文件。打开 composer.json 添加下面的内容:1
2
3
4
5
6"autoload": {
...
"files": [
"app/helpers.php"
]
},
运行 composer dump-autoload ,然后继续。
现在我们已经解决了之前的那个错误,我们 现在需要发布这个包的配置文件。1
php artisan vendor:publish --provider="Tymon\JWTAuth\Providers\JWTAuthServiceProvider"
此时,你会看到另外一个错误提示 There are no commands defined in the “vendor” namespace.
这是因为 Lumen 默认没有 vender:publish 命令。我创建了一个扩展包,可以解决这个问题。安装扩展包: VendorPublishCommand。
按照这个扩展包的描述文件,添加 vendor:pulish 命令到 Lumen 中。完成之后重新运行命令:
1 | php artisan vendor:publish --provider="Tymon\JWTAuth\Providers\JWTAuthServiceProvider" |
要完成所有的安装,这里还有一个可选的步骤:adding facades。
Adding facades
我发现在 Lumen 中设置一个 facade 最简单的方法是将其添加到 bootstrap/app.php 中。
为了能够使用 JWT 配置文件,我们必须添加:1
$app->configure('jwt');
在 bootstrap/app.php 中声明,在 $app->withFacades() 的下面。
现在我们添加这个 facades:
1 | class_alias('Tymon\JWTAuth\Facades\JWTAuth', 'JWTAuth'); |
继续安装过程,最后一步是生成一个密匙。这个命令可以生成一个鄙视并保存到配置文件中。1
php artisan jwt:generate
至此完成 facade 的添加。
配置
在这一部分,你要检查配置文件,并且根据你的需要修改配置文件。打开 config/jwt.php,亦可以看到之前生成的密匙。你可以移动这个密匙到 .env 中。我没有在这里做任何改变,如果你想理解这些配置文件可以查看这个文档。
一个使用 Postman 测试 API 的提示。当你使用 PUT,PATCH 方法时,确认使用了 x-www-form-urlencoded 选项,而不是默认的 form-data。
认证
我们希望能够指定哪些路由需要认证,为了做到这一点,我们需要注册 JWT 中间件。
打开 bootstrap/app.php ,找到 Register Middleware 部分,取消 routeMiddleware 的注释,并添加以下内容:1
2
3
4$app->routeMiddleware([
'jwt.auth' => Tymon\JWTAuth\Middleware\GetUserFromToken::class,
'jwt.refresh' => Tymon\JWTAuth\Middleware\RefreshToken::class,
]);
一旦中间件在引导文件中定义,你可以在路由 routes.php 中使用 middleware 关键词。只有 store,update 和 destory 路由要求认证,所以像下面这样修改路由。
1 | $app->group(['prefix' => 'projects', 'middleware' => 'jwt.auth'], function($app) { |
如果你试图触发热和使用 jwt.auth 中间件的路由,你会得到下面的错误:1
Class Illuminate\Routing\ResponseFactory does not exist
解决这个问题,我们需要运行一下命令,添加 illuminate/routing 包。1
composer require illuminate/routing
好了,现在当我们试图发送一个 POST 请求时,我们会得到这样的响应1
2
3{
"error": "token_invalid"
}
这意味这我们必须登录(获得 token)后才能进行这个操作。这也意味着认证已经起作用了。现在让我们获得令牌。
获得令牌(登录)
我们在对 API 执行任何 POST,PUT,DELETE时,必须先登录,也就是说我们需要在每一次请求中带上一个 token。
据我所知 Lumen 并没有开箱即用的验证,所以我们需要创建一个 auth/login 路由接收 email 和 密码,并在登录成功后返回 JWT token。
首先,我们创建一个登录的路由:1
$app->post('auth/login', 'App\Http\Controllers\Auth\AuthController@postLogin');
现在我们创建控制器在app/Http/Controllers/Auth/AuthController.php:
1 | <?php |
我使用 php artisan tinker 创建了一个虚拟用户,你可以使用任意的办法在数据库中创建一个用户。
现在,当你发送一个包含 email 和 password 的请求到 auth/login,你将获得一个像这样的响应:1
2
3{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXUyJ9.eyJzdWIiOjEsImlzcyI6Imh0dHA6XC9cL2x1bWVuLnRyZWVsaW5lLmFwcFwvYXV0aFwvbG9naW4iLCJpYXQiOiIxNDM1MjI4MDk2IiwiZXhwIjoiMTQzNTIzMTY5NiIsIm5iZiI6IjE0MzUyMjgwOTYiLCJqdGkiOiJmZjJhOTZkYjI4YTY2MzY5ZmNmZjZjNDEyYWRkNjdiMyJ9.M2NjNzY3NGU4NGM1MGI2ZDA4MTlhZmE5MGYwNjE5MzNmNGFlNmEyZTJmNTgwMjQ4MjUzMzAyZjQxMmI1MjViNQ"
}
你要记得收到的这个 token,因为我们需要使用它构造请求。
访问受保护的路由(使用 token)
为了能够访问 API 中要求验证的部分,你需要像下面这样设置一个认证头:
1 | Authorization: Bearer {yourtokenhere} |
现在,在你需要验证的方法中,你可以使用下面的方法:1
$user = JWTAuth::parseToken()->authenticate();
参考文章:http://laravelista.com/json-web-token-authentication-for-lumen/