实战:使用 Lumen 和 Vue 构建个人清单应用(三)开发用户模块接口

559 阅读2分钟

这是我参与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 测试,返回成功。 image.png 好,我们开始写业务部分,注册的时候,我们接收前端传入的邮箱和密码,首先我们得去数据库查询该邮箱是否已存在,如果已经有用户注册了该邮箱,则不允许下一步操作,否则往数据库插入新的数据,完整代码如下:

/**
  * 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 的账号,测试成功~ image.png

实现登录接口

现在我们有了一个刚刚注册的账号,那就用这个账号来进行登录的调试,登录要验证账号是否存在以及密码是否正确,若登录成功则返回 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_infotoken,这样前端就可以使用 token去访问其它接口了。 image.png

实现登出接口

登出功能实际是让 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值,中间有个空格连接。 image.png 但是这里要注意,如果没有传入 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 已经过期,则会返回以下内容: image.png

欢迎阅读其它文章