最近遇到一个问题,就是前端使用vue的框架,使用了反向代理是可以正常访问的我Api接口的;后来取消了反向代理之后,后端就无法正常的保存cookie作为登录判断条件了。
解决的方法:
后端生成一个随机字符串作为Token,保存在数据库;然后返回给前端,前端在 header 头上面带着访问其他Api接口,后端就拿 header 里面的 token 作为登录判断,来验证是否有没有登录。
示例代码:
Login 登录类
<?php
class Login
{
public function signIn()
{
try{
//查询用户信息
$user = User::find()->select(['mobile','login_pass','id'])->where(['mobile' => $this->mobile])->asArray()->one();
//判断如果用户不存在,返回错误信息
if(empty($user)){
throw new \Exception('手机号码不存在');
}
//如果密码是空的
if(empty($user['login_pass'])){
//生成一个临时密码,手机后4位 + 123456
$pass = md5(md5(substr($this->mobile,-4).'123456'));
}else{
//否则,密码为查询出来的密码
$pass = $user['login_pass'];
}
//如果提交过来的密码不等于正确的密码,返回错误
if(md5(md5($this->password)) != $pass){
throw new \Exception('密码错误');
}
//生成随机 token ,然后md5加密
$token = md5(md5(rand(0000,9999).chr(rand(65,90)).chr(rand(97,122)).chr(rand(65,90)).$user['id'].rand(0000,9999).$user['mobile'].chr(rand(97,122)).chr(rand(65,90)).chr(rand(97,122)).time().rand(0000,9999)));
//查询用户ID是否存在
$Login = LoginToken::find()->where(['user_id' => $user['id']])->asArray()->one();
//登录过期时间
$time = time() + 3600 * 24;
//如果用户存在
if($Login){
//重新修改Token
\Yii::$app->db->createCommand()->update(LoginToken::tableName(), [
'token' => $token,
'update_at' => $time
], 'user_id = '.$user['id'])->execute();
}else{
///不存在,生成一个新的Token
\Yii::$app->db->createCommand()->insert(LoginToken::tableName(), [
'user_id' => $user['id'],
'token' => $token,
'created_at' => time(),
'update_at' => $time
])->execute();
}
//返回成功信息
return [
'code' => ApiCode::CODE_SUCCESS,
'msg' => '登录成功',
'data' => $token //token返回给前端,前端获取到后,放在header的token里面,后端即可获取
];
} catch (\Exception $e){
//返回错误信息
return [
'code' => ApiCode::CODE_ERROR,
'msg' => $e->getMessage(),
];
}
}
}
token 验证类
<?php
class Token
{
public static function isToken()
{
//Yii框架获取 header 参数
$headers = \Yii::$app->getRequest()->getHeaders();
//取出 Token 值
$token = $headers->get('token');
//判断没有 Token 就返回需要登录信息
if(empty($token)){
//没有token,也需要重新登录
return [
'code' => -1,
'msg' => '请登录',
];
}
//Yii 根据Token 查询数据
$token = LoginToken::find()->select(['token','user_id','update_at'])->where(['token' => $token])->asArray()->one();
//如果当前时间大于或等于数据库保存的登录时间,则返回登录过期信息
if($token['update_at'] <= time()){
//未登录
return [
'code' => 0,
'msg' => '登录过期',
];
}
//否则,返回登录的用户ID号
return $token['user_id'];
}
}
User 实现类
<?php
use Token;
class User extends Token
{
public function index()
{
//获取验证Token类的方法返回的数据
$user_id = Token::isToken();
//如果返回的是数据,证明是报错的信息,则直接返回给前端
if(is_array($user_id)){
return $user_id;
}
//如果返回的不是数组,就是用户的ID号
//在下面就可以拿用户的ID号做业务处理
}
}
|