用户注册
我们在 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 接口