环境
1.php7.4.3,mysql8.0,postman
2.文件,路由,控制器
一、登录逻辑
1.判断用户是否登录,登录后将token塞进header中,如果登录则正常使用,未登录跳转首页;
2.验证token将token,id,username存放进redis中
3.可以使用session或者cookie缓存这两个会更简单些
二、生成token存放在redis中
1.在app\admin\business\Token,php
<?php
/**
*Created by giveLive
*user:lingm
*Date:2021/10/10
*timer:下午 2:45
*Atom:现在的努力是为了小时候吹过的NB
**/
namespace app\admin\business;
use app\BaseController;
use app\model\mysql\User;
use Firebase\JWT\JWT;
use app\admin\business\Time;
class Token {
protected $salt = null;
public function generateToken(){
$username = input("username","");
if (empty($username)){
return show(config("code.status.error"),"用户名不能为空");
}
$userObj = new User();
$user = $userObj ->getUserByname($username);
$id = $user['id'];
$username = $user['username'];
if(empty($user)){
return show(config("code.status.error"),"用户不存在");
}
$url = request()->url();
$currentTime = time();
$exp = $currentTime + config("jwt.exp");
$data = array(
"iss" => "", //签发者 可以为空
"aud" => $username , //面象的用户,可以为空
"url" => $url, //访问的url地址
"iat" => $currentTime, //签发时间
"nbf" => $currentTime, //立马生效
"data" => [ //记录的id的信息,这里是自已添加上去的,如果有其它信息,可以再添加数组的键值对
'id' => "id",
]
);
$token = JWT::encode($data,$this->salt,"HS256");
$redis = [
'id' => $id,
'username' => $username,
'access-token' => $token,
];
$res = cache(config("jwt.token").md5($username),$redis,Time::getLoginTime('type'));
return $res ? json(["token" => $token,"username" => $username]) : false;
return $res;
}
生成这是根用户表中用户名和id以及当前时间生成的token,将生成的token,id,用户名放进redis中,在登录界面进行验证redis中的数据
Time代表redis的过期时间,
Time中的代码
class Time
{
/**
* 如果type = 1 为一周
* 如果$type = 2 为一个月 “30“天的一个月
* @param int $type
* @return float|int
*/
public static function getLoginTime($type = 2){
$type = !in_array($type,[1,2]) ? 2 :$type;
if ($type == 1){
$day = $type * 7 ;
}elseif ($type == 2){
$day = $type * 30;
}
return $day * 24 *3600;
}
}
3.model自行创建用户信息获取
4.Login中验证获取token继承Authbasecontroller
//继承Authbasecontroller判断用户是否登录,
//涉及到需要用户登录的继承Authbasecontroller
//未涉及用户登陆的继承UserBaseController
class Login extends Authbasecontroller
{
//重定向initialize
public function initialize()
{
parent::initialize(); // TODO: Change the autogenerated stub
}
public static function login()
{
//判断是否时post请求
if (!request()->isPost()){
return show(config("code.status.error"),"非法请求");
}
//接受表单$username $email(选参) $password $code
$username = input("username","");
$email = input("email","");
$password = input("password","");
$code =input("code","");
//使用model,获取用户信息
$userObj = new User();
$user = $userObj->getUserByname($username);
$email = $user['email'];
if (empty($username) || empty($password) || empty($code)){
return show(config("code.status.error"),"验证码不能为空");
}
//获取存redis中的邮箱验证码
$getCode = Cache::get(config("redis.code_email").$email);
//判断用户输入的验证码是否等于redis中的验证码
if ($getCode != $code){
return show(config("code.status.error"),"验证码错误",$user);
}
if (empty($user)){
return show(config("code.status.error"),"用户不存在");
}
if ($user['password'] != md5($password.'_abc_')){
return show(config("code.status.error"),"密码错误");
}
if (empty($email)){
return show(config("code.status.error"),"邮箱为空",$user['email']);
}
if ($getCode != $code){
return show(config("code.status.error"),"验证码错误",$code);
}
//使用business定义的生成token
$tokenObj = new Token();
$token = $tokenObj->generateToken();
if (empty($token)){
return show(config("code.status.error"),"token为空");
}
$id = $user['id'];
$updateDate = [
'create_time' => time(),
'login_ip' => request()->ip(),
'login_time' => time(),
'update_time' => time(),
];
$usere = $userObj->updateUser($username,$updateDate);
if (empty($usere)){
return show(config("code.status.error"),"登陆失败",$updateDate);
}
$tokens = Cache::get(config("jwt.token").md5($username));
$userss= [
'id' => $user['id'],
'username' => $user['username'],
'email' => $user['email'],
'create_time' => $user['create_time'],
'update_time' => $user['update_time'],
'login_time' => $user['login_time'],
'login_ip' => $user['login_ip'],
"token" => $tokens,
];
if (empty($tokens)){
return show(config("code.status.error"),"token错误");
}
//将上方的id,username,token存进redis
cache(config("redis.code_user").$username,md5(md5($username)));
return show(config("code.status.success"),"登陆成功",$userss);
}
}
三、Authbasecontroller和UserBaseController
1.Authbasecontroller涉及到用户登录的代码,才可以继承,用户无需登录继承UserBaseController
Authbasecontroller如下
class Authbasecontroller extends UserBaseController
{
定义全局属性
public $acessToken = null;
public $userId = 0;
public $username = null;
public function initialize()
{
parent::initialize(); // TODO: Change the autogenerated stub
//获取请求的token塞进header中
$this -> acessToken = $this->request->header("acess-token");
//判断islogin中有没有token和用户信息
//如果islogin中没有获取到则不成立返回错误信息
if (!$this->acessToken || !$this->isLogin()){
//在UserBaseController中定义一个show方法传递动态参数
//然后使用$this调用即可
return $this->show(config("code.status.error"),"请先登录");
}
}
public function isLogin(){
$username = input("username","");
//获取redis中的token
$res = cache(config("jwt.token").md5($username));
if (!$res){
return false;
}
if (!empty($res['id']) || !empty($res['username'])){
$this->userId = res['id'];
$this-> username = $res['username'];
return true;
}
dump($res);
}
}
2.UserBaseController中传递冬天参数
UserBaseController
class UserBaseController extends BaseController
{
public function initialize()
{
parent::initialize(); // TODO: Change the autogenerated stub
}
//传递动态参数args
public function show(...$args){
throw new HttpResponseException(show(...$args));
}
}
持续更新下一篇,敬请期待下一篇
|