当前位置:首页 > 开始使用Lumen吧 - 登陆 / 注册

开始使用Lumen吧 - 登陆 / 注册

发布于 2018-05-07 阅读 397 次 框架 Lumen PHP

用户注册

我们在 Controller/Controller.php 添加 succeed 和 faied 公用接口数据返回方法
通过 status_code 来区分失败和成功

namespace App\Http\Controllers;

use Laravel\Lumen\Routing\Controller as BaseController;

class Controller extends BaseController
{
    /**
     * 返回成功
     *
     * @param array $data
     * @param string $msg
     * @param int $code
     *
     * @return \Illuminate\Http\JsonResponse
     */
    public function succeed($data = [], $msg = "successd", $code = 0)
    {
        return response()->json(['msg' => $msg, 'state_code' => $code, 'data'=> $data]);
    }

    /**
     * 返回失败
     *
     * @param string $msg
     * @param int $code
     * @return \Illuminate\Http\JsonResponse
     */
    public function faied($msg = "failed", $code = -1)
    {
        return response()->json(['msg' => $msg, 'state_code' => $code]);
    }
}

开启 Eloquent ORM

bootstrap/app.php

$app = new Laravel\Lumen\Application(
    realpath(__DIR__.'/../')
);

// 开启 Eloquent, 默认被注释
$app->withEloquent();

配置 Mysql 数据库连接

.env

DB_CONNECTION=mysql
DB_HOST=数据库地址(127.0.0.1)
DB_PORT=数据库端口 (3306)
DB_DATABASE=数据库
DB_USERNAME=用户名
DB_PASSWORD=密码

创建数据表 user

# 用户表数据结构
CREATE TABLE `user` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `username` varchar(100) NOT NULL DEFAULT '',
  `email` varchar(100) NOT NULL DEFAULT '',
  `password` varchar(60) NOT NULL DEFAULT '',
  `api_token` varchar(60) NOT NULL DEFAULT '',
  `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  `updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8

创建 User 模型(Model)

新建 app/Models 文件夹,复制 User.php 至 当前文件 Models 下并修改 第一行 namespace
添加 Models 文件夹用来分类管理我们的模型

namespace App\Models;

Controller 下新建 Auth 并创建 AuthController.php

/**
 * AuthController.php
 *
 * PHP version 7
 *
 * @category  PHP
 * @package   lumen
 * @author    w2le
 * @copyright 2018/5/4
 */

namespace App\Http\Controllers\Auth;

use App\Models\User;
use Illuminate\Http\Request;
use Hautelook\Phpass\PasswordHash;
use App\Http\Controllers\Controller;

class AuthController extends Controller
{

    /**
     * 用户注册
     *
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse json
     */
    public function signup(Request $request)
    {
        // 参数校验
        $this->validate($request, [
            'username' => 'required',
            'email'    => 'required|email',
            'password' => 'required'
        ]);

        $username =  $request->input('username');
        $email    =  $request->input('email');
        $password =  $request->input('password');

        // 注册记录校验
        $row = User::where('username', $username)->orWhere('email', $email)->first();

        if($row !== null) {
            return $this->faied("当前邮箱或用户名已被注册");
        }

        $passwordHasher = new PasswordHash(8,false);

        // 插入数据
        $user = new User();
        $user->username = $username;
        $user->email    = $email;
        $user->password = $passwordHasher->HashPassword($password);

        if($user->save() === false) {
            return $this->faied("用户注册失败");
        }

        return $this->succeed();
    }
}

password 加密

现在还有很多人通过 MD5 来对密码加密。其实这是一种错误的做法。MD5 只是一种摘要算法,而且 MD5 并不安全。这里我们通过使用 phpass 来保护我们的密码

在我们的 composer.json中添加 "hautelook/phpass": "1.0.0" 并执行 composer update

"require": {
    "php": ">=5.6.4",
    "laravel/lumen-framework": "5.5.*",
    "vlucas/phpdotenv": "~2.2",
   "hautelook/phpass": "1.0.0"
},

用户登陆

/**
 * 用户登陆
 *
 * @param Request $request
 * @return \Illuminate\Http\JsonResponse json
 */
public function signin(Request $request)
{

    $this->validate($request, [
        'email'    => 'required',
        'password' => 'required'
    ]);

    $email    =  $request->input('email');
    $password =  $request->input('password');

    $user = User::Where('email', $email)->first();

    if($user == null) {
        return $this->faied("当前用户不存在");
    }

    $passwordHasher = new PasswordHash(8,false);

    // 校验密码
    if($passwordHasher->CheckPassword($password, $user->password) === false) {
        return $this->faied("用户名或密码错误");
    }

    // 生成登陆令牌
    $user->api_token = str_random(60);

    if($user->save() === false) {
        return $this->faied("登陆错误");
    }

    return $this->succeed(['token'=> $user->api_token]);
}

令牌 token 的生成可以根据自身业务需求来生成。
如果有使用 reids 之类数据库做缓存,可以把 api_token 放入 redis 中,并设置过期时间为 api_token 有效期

添加路由
给我们的 AuthController 添加路由映射 routes/web.php

// 注册路由...
$router->post('signup', 'Auth\AuthController@signup');
// 登陆路由...
$router->post('signin', 'Auth\AuthController@signin');

认证授权

开启认证服务

注册 Auth 认证服务 bootstrap/app.php

/*
|--------------------------------------------------------------------------
| Register Service Providers
|--------------------------------------------------------------------------
|
| Here we will register all of the application's service providers which
| are used to bind services into the container. Service providers are
| totally optional, so you are not required to uncomment this line.
|
*/

 $app->register(App\Providers\AuthServiceProvider::class);

修改 app\Providers\AuthServiceProvider.php User 模型 namespace

namespace App\Providers;

use App\Models\User;
// 原为 App\User;


/**
 * 此为验证 api_token 方法
 * Boot the authentication services for the application.
 *
 * @return void
 */
public function boot()
{
    // Here you may define how you wish users to be authenticated for your Lumen
    // application. The callback which receives the incoming request instance
    // should return either a User instance or null. You're free to obtain
    // the User instance via an API token or any other method necessary.

    $this->app['auth']->viaRequest('api', function ($request) {

        if ($request->header('token')) {
        // 原 api_token 是放于请求参数中,这里修改 token 置于 header 中

            return User::where('api_token', $request->header('token'))->first();
            // 如果 api_token 是存放在 redis 或其他地方,只需要修改这一步的 token 校验
        }
    });
}

注册 Auth 中间件 bootstrap/app.php

/*
|--------------------------------------------------------------------------
| Register Middleware
|--------------------------------------------------------------------------
|
| Next, we will register the middleware with the application. These can
| be global middleware that run before and after each request into a
| route or middleware that'll be assigned to some specific routes.
|
*/

$app->routeMiddleware([
    'auth' => App\Http\Middleware\Authenticate::class,
]);

给需要登陆验证的路由添加 Auth 认证保护

$router->group(['middleware' => 'auth'], function () use ($router) {

    // 需要登陆认证的路由
    $router->get('/', 'ExampleController@Index');

});

API 认证

打开 app/Http/Middleware/Authenticate.php

/**
 * 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)
{
    // 验证访问用户是否是游客
    // 未携带正确的 api_token
    if ($this->auth->guard($guard)->guest()) {

        //return response('Unauthorized.', 401);

        //这里我们可以修改为我们统一的 json 返回数据格式
         return response()->json(['msg' => "未授权的访问", 'state_code' => 401]);
    }

    return $next($request);
}

令牌使用

在登陆后,客户端维护好服务端返回的 token。每次请求时,客户端只需要在 header 中携带 token

关于如何调试我们刚创建好的接口,以及如何添加 header 头。可以查看相关文章 让 Postman 来帮助你调试 API 接口