这是我参与8月更文挑战的第29天,活动详情查看:8月更文挑战
用户模块接口
实现用户注册接口
用户注册不需要登录认证,是一个简单的数据新增的操作,在 UserController.php 中新建 register 方法。
/**
* register function
* 用户注册
* @param Request $request
* @return void
*/
public function register(Request $request)
{
return Util::ajaxMsg('0', 'success');
}
Lumen 是根据 Request 去获取请求参数的,所以该方法需要加上 Request $request 参数。 注意,文件头部务必 use 相关文件,如下:
<?php
namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
use App\Lib\Util;
use App\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Tymon\JWTAuth\Facades\JWTAuth;
在路由中添加一条/user/register,注意请求方式是 POST 。
// 用户注册
$router->post('/user/register', 'UserController@register');
使用 Postman 测试,返回成功。
好,我们开始写业务部分,注册的时候,我们接收前端传入的邮箱和密码,首先我们得去数据库查询该邮箱是否已存在,如果已经有用户注册了该邮箱,则不允许下一步操作,否则往数据库插入新的数据,完整代码如下:
/**
* register function
* 用户注册
* @param Request $request
* @return void
*/
public function register(Request $request)
{
// 获取传入的全部参数
$request = $request->all();
// 查询该邮箱是否已被注册
$data = User::where('email', $request['email'])->first();
if ($data) {
return Util::ajaxMsg('-1', '该邮箱已被注册');
}
$newUser = new User;
$newUser->id = Util::createId(); // 生成 11 位 UID
$newUser->email = $request['email']; // 传入的邮箱
$newUser->nick_name = $request['email']; // 默认为传入的邮箱
$newUser->password = Hash::make($request['password']); // 使用 Hash 加密传入的密码
$newUser->sex = 1; // 默认为1-男性
return $newUser->save() ? Util::ajaxMsg('0', '注册成功') : Util::ajaxMsg('-1', '注册失败');
}
新增一个 test@qq.com ,密码为 123456 的账号,测试成功~
实现登录接口
现在我们有了一个刚刚注册的账号,那就用这个账号来进行登录的调试,登录要验证账号是否存在以及密码是否正确,若登录成功则返回 token 和用户信息(user_info),否则给予提示。
Lumen 通过 JWTAuth::attempt 获取 token ,在此之前要获取用户表中的主键(id)和传入的密码(password)对应,JWT 会自动的去匹配数据库这两个字段的值,如果验证成功,则会返回 token。
接口完整代码如下:
/**
* login function
* 用户登录
* @param Request $request
* @return void
*/
public function login(Request $request)
{
// 获取传入的全部参数
$request = $request->all();
// 查询账号是否存在
$user = User::where('email', $request['email'])->first();
if (!$user) {
return Util::ajaxMsg('-1', '账号不存在');
}
$request['id'] = $user->id;
// 密码校验
if (!$token = JWTAuth::attempt($request)) {
return Util::ajaxMsg('-1', '账号或密码输入错误');
}
// 认证通过返回数据
$user_info = User::where('id', $request['id'])->first();
$data = [
'user_info' => $user_info,
'auth' => [
'token' => $token,
'token_type' => 'Bearer',
'expires_in' => JWTAuth::factory()->getTTL() * 60,
],
];
return Util::ajaxMsg('0', '登录成功', $data);
}
// 用户登录
$router->post('/user/login', 'UserController@login');
用刚刚注册的账号去登录,登录成功,同时返回 user_info和 token,这样前端就可以使用 token去访问其它接口了。
实现登出接口
登出功能实际是让 token 失效,当这个 token 再次请求其它接口的时候进行拦截,由于集成了 Lumen 的 JWT,让 token 失效其实很简单,如下:
/**
* logout function
* 登出
* @return void
*/
public function logout()
{
JWTAuth::parseToken()->invalidate();
return Util::ajaxMsg('0', '退出成功');
}
路由
// 用户登出
$router->post('/user/logout', 'UserController@logout');
在请求接口的时候,在头部加入 Authorization ,值为 Bearer + token值,中间有个空格连接。
但是这里要注意,如果没有传入 token,也就是用户未登录的情况下,去请求该接口,是应该要提示未登录或 token
已过期的,总不能每个接口都去写一份这样的代码吧,当然不能,所以我们用中间件去过滤这个传入的 token 是否有效。
改造 appHttpMiddlewareAuthenticate.php 文件如下:
<?php
namespace App\Http\Middleware;
use Closure;
use App\Lib\Util;
use Illuminate\Contracts\Auth\Factory as Auth;
class Authenticate
{
/**
* The authentication guard factory instance.
*
* @var \Illuminate\Contracts\Auth\Factory
*/
protected $auth;
/**
* Create a new middleware instance.
*
* @param \Illuminate\Contracts\Auth\Factory $auth
* @return void
*/
public function __construct(Auth $auth)
{
$this->auth = $auth;
}
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @param string|null $guard
* @return mixed
*/
public function handle($request, Closure $next, $guard = null)
{
// Token无效过滤
if ($this->auth->guard($guard)->guest()) {
return Util::ajaxMsg('401', 'Token过期或无效', '', 401);
}
return $next($request);
}
}
然后在路由中,新建个路由组,并用该中间件过滤里面的路由,把需要过滤的路由放进去,修改后如下:
// 需要登录验证的接口组
$router->group(['middleware' => 'auth'], function () use ($router) {
// 用户登出
$router->post('/user/logout', 'UserController@logout');
});
此时,若登出的时候头部没有 token 或 token 已经过期,则会返回以下内容: