JWT之登录、登出、验证码接口
6.2 验证码接口
验证码接口用于登录页面展示时,获取验证码图片地址及验证码标识
composer require topthink/think-captcha 1.*
设置路由,application/route.php中,adminapi域名路由部分,增加代码如下
1 2 3 | //验证码图片 Route::get( 'captcha/:id' , "\\think\\captcha\\CaptchaController@index" ); //访问图片需要 Route::get( 'captcha' , 'adminapi/login/captcha' ); |
在login控制器中添加
<?php namespace app\adminapi\controller; use think\Controller; class Login extends BaseApi { /** * 获取验证码图片地址 */ public function captcha() { //验证码标识 $uniqid = uniqid(mt_rand(100000, 999999)); //返回数据 验证码图片路径、验证码标识 $data = [ 'src' => captcha_src($uniqid), 'uniqid' => $uniqid ]; $this->ok($data); } }
{ "code":200, "msg":"success", "data":{ "src":"http:\/\/adminapi.pyg.com\/captcha\/7873845d27250ede217.html", "uniqid":"7873845d27250ede217" } }
可根据实际需要,对验证码进行自定义配置: application/config.php
验证码组件,默认将验证码中的字符,存放在session中。
考虑到部分客户端(比如手机app) ,一般不使用session(显示验证码的请求和登录的请求,其session会话彼此独立)。
可修改组件源代码如下:
vendor/topthink/think-captcha/src/Captcha.php 的entry方法中
后续验证时,先从缓存取出对应的session_id, 并设置session_id。 见登录接口。
②设置路由,application/route.php中,adminapi域名路由部分,增加代码如下
//登录 Route::post('login', 'adminapi/login/login');
③封装密码加密函数
注意:后台管理员表tpshop_admin中 初始的管理员密码,需要自己加密一个初始密码,更新到数据表
使用自定义的密码加密函数:
④登录功能
/** * 登录接口 */ public function login() { //获取输入变量 $param = input(); $validate = $this->validate($param, [ 'username' => 'require', 'password' => 'require', 'code' => 'require', 'uniqid' => 'require' ]); if($validate !== true){ $this->fail($validate); } //根据验证码标识,从缓存取出session_id 并重新设置session_id session_id(cache('session_id_'.$param['uniqid'])); //进行验证码校验 使用手动验证方法 if (!captcha_check($param['code'], $param['uniqid'])) { //验证码错误 $this->fail('验证码错误'); } //根据用户名和密码(加密后的密码),查询管理员用户表 $where = [ 'username' => $param['username'], 'password' => encrypt_password($param['password']) ]; $info = \app\common\model\Admin::where($where)->find(); if(!$info){ //用户名或者密码错误 $this->fail('用户名或者密码错误'); } $data['token'] = \tools\jwt\Token::getToken($info->id); $data['user_id'] = $info->id; $data['username'] = $info->username; $data['nickname'] = $info->nickname; $data['email'] = $info->email; //登录成功 $this->ok($data); }
/** * 后台退出接口 */ public function logout() { //清空token 将需清空的token存入缓存,再次使用时,会读取缓存进行判断 $token = \Token::getRequestToken(); $delete_token = cache('delete_token') ?: []; $delete_token[] = $token; cache('delete_token', $delete_token, 86400); $this->ok(); }
登录检测
在application/adminapi/controller/BaseApi.php中进行检测。
①设置无需检测方法列表
//无需进行登录检测的请求 protected $no_login = ['login/login', 'login/captcha'];
②进行检测
try{ $path = strtolower($this->request->controller()) . '/' . $this->request->action(); if(!in_array($path, $this->no_login)){ $user_id = \tools\jwt\Token::getUserId(); //登录验证 if(empty($user_id)){ $this->fail('未登录或Token无效', 403); } //将获取的用户id 设置到请求信息中 $this->request->get(['user_id' => $user_id]); $this->request->post(['user_id' => $user_id]); } }catch(\Exception $e){ $this->fail('服务异常,请检查token令牌', 403); }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?