uniapp 开发,thinkphp实现用户登录api

用户登录核心代码

用户登录的核心思路与传统的登录基本相同,不同的地方就是web开发中使用session或者cookies来进行授权验证,在接口开发中,由于接口的大部分使用场景是跨域的,所以一般采用令牌来实现授权限证。

实现思路

当用户登录成功后,在服务器端生成令牌token并在服务器端存储,然后下发到客户端,当用户访问需要授权的接口时,需要携带该令牌,然后在务器端完成验证。

在这里令牌需要具体一下特点:

  1. 由服务器端生成并存储
  2. 惟一性
  3. 具有生命周期
    //用户登录
    Route::post("/:ver/login", ":ver.Login/login");

    创建app\api\constroller\v1\Login.php控制器

    php think make:controller api@v1/Login

    登录方法

    public function login(Request $request){
            //1. 数据验证
            (new LoginValidate())->runCheck();
            //2.登录验证,到数据库中查询用户信息
    ,并生成令牌
            $data = $request->post();
            (new User())->checkLogin($data);
            //4.响应
            $datas = [
                'username'=>$data['username'],
                'token'=>$token
            ];
            return $this->return_msg('ok',$datas,0,200);

    创建验证器app\api\validate\Login.php

namespace app\api\validate;
use app\api\libs\Sendsms;
class Login extends BaseValidate
{
    /**
     * 定义验证规则
     * 格式:'字段名'	=>	['规则1','规则2'...]
     *
     * @var array
     */	
	protected $rule = [
        'username'=>"username|require|mobile",
        'password'=>"password|require|min:6",
    ];
    
    /**
     * 定义错误信息
     * 格式:'字段名.规则名'	=>	'错误信息'
     *
     * @var array
     */	
    protected $message = [
        'username.require'=>"用户名不能为空",
        'username.mobile'=>"用户名必须是手机号",
        'password.require'=>"密码不能为空",
        'password.min'=>"密码长度不能小于6位",
    ];
}

user模型中checkLogin方法

//用户登录
publicstaticfunctioncheckLogin($data){
//1.查询用户信息,根据用户名查询
$user\=self::where('username','=',$data\['username'\])\->field(\['id,username,password'\])\->find();
if(!$user){
thrownewHttpExceptions(403,"账号不存在",10000);
        }
//验证密码是否正确
if(password\_verify($data\['password'\],$user\['password'\])){
returntrue;
        }
thrownewHttpExceptions(403,"密码不正确",10001);
    }

令牌授权时,需要生成令牌和令牌验证,为了方便后期的扩展,在这里直接编写成一个独立的类库来实现这一功能。

app\api\libs\下创建类文件Auth.php

<?php

namespace app\api\libs;

use app\api\model\User;
use app\exception\HttpExceptions;
use think\facade\Request;

/**
 * 1.生成令牌
 * 2.设置登录状态
 * 3.验证登录状态
 * Class Auth
 * @package app\api\libs
 */
class Auth
{
    private $token = '';
    private $username = '';
    private static $instance = null;

    private function __construct()
    {
        $request  = Request::instance();
        $this->username = $request->post('username');
        $this->token = $request->param('token');
    }

    private function __clone()
    {
        // TODO: Implement __clone() method.
    }
    //统一的入口
    public static function getInstance(){
        if(!self::$instance instanceof self){
            self::$instance = new self();
        }
        return self::$instance;
    }

    //获取token
    public function getToken(){
        return $this->token;
    }

    //生成token

    private function createToken(){
        $this->token = md5($this->username.time().rand(100000,999999));
    }

    //设置token 保持登录状态
    public function setToken(){
        $this->createToken();
        //写入数据表
        $user = (new User())->where('username','=',$this->username)->find();
        $user->login_code = $this->token;
        $user->expiration_time = time()+config('auth.expire_time');
        $user->save();
        return $this;
    }

    //验证,10006:无权限
    public function checkLogin(){
        //1.到数据库中查询用户信息,token
        $user = (new User())->where('login_code','=',$this->token)->find();
        if(!$user){
            throw new HttpExceptions(403,"无权限",10006);
        }
        //2. 登录是否过期   10007:超时
        if($user['expiration_time']<time()){
            throw new HttpExceptions(403,"登录超时",10007);
        }
        //延期过期时间
        if(($user->expiration_time-time())<5){
            $user->expiration_time = time()+config('auth.expire_time');
            $user->save();
        }
        // echo $user->expiration_time."\n";
        return true;
    }
}

用户的登录授权验证这一块,为了后期扩展的方便,所以在这里咱们将其放到中间件中处理。然后在路由中调用中间件进行验证。

创建中间件app\middleware\CheckApiLogin.php

<?php
namespace app\middleware;
use app\api\libs\Auth;
class CheckApiLogin
{
    public function handle($request, \Closure $next)
    {
        // 令牌验证
        Auth::getInstance()->checkLogin();
        return $next($request);
    }
}

设置中间件别名,需要在配置文件中设置,在对应应用配置目录下新建middleware.php配置文件

<?php
return [
    'alias' => [
        'check' => \app\middleware\CheckApiLogin::class
    ],
];

在需要授权验证的路由上添加上验证中间件即可。

Route::post('/:ver/test1',":ver.Login/test1")\->middleware('check');
Route::post('/:ver/test',":ver.Login/test")->middleware('check');

  • 9
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值