小程序和ThinkPHP5结合实现登录状态(附代码)

Posted on Posted in PHP教程

本篇文章给大家带来的内容是关于小程序和ThinkPHP5结合实现登录状态(附代码),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。

微信小程序中,一般会涉及三种登录方式:
1. 使用微信账号登录
2. 自有的账号注册和登录
3. 使用其他第三方平台账号登录

微信账号登录流程:

1. 小程序通过wx.login获取code,发往后台,后台以此向微信API换取session_key和openid;
2. 随机生成字符串作为sessionid(key),session_key和openid作为value,存入redis中,为了安全,
存入的时候还应设置一个超时的时间;
3. 客户端将返回的sessionid存入storage,调用那些需要登录后才有权限的访问的后台服务时,
你可以将保存在storage中的sessionid取出并携带在请求中,后台代码中获取到该sessionid后,
从redis中查找是否有该sessionid存在,存在的话,即确认该session是有效的,
继续后续的代码执行,否则进行错误处理。

本文采用的是自由的账号注册和登录,主要思路和流程如下:

1. 进入小程序首先通过wx.login获取code,通过后台接口发往后台,后台以此向微信API换取session_key和openid;
2. 判断数据库中有无该openid【唯一标识,需和账号(手机号)绑定】,
— 如果数据库中没有该openid(说明没有该账号):
判断传过来的手机号是否为空(登录时会将手机号存到全局变量),如果不为空,则说明是刚登录过的,然后绑定openid及openid_time(当前时间),
如果手机号也为空,说明没登录过,则返回登录失败信息,使客户端跳转登录页;
— 如果数据库中有该openid(说明数据库中有相对应的手机号),
判断openid_time距现在的时间是否大于4小时,如果大于,返回登录失败信息,使客户端跳转登录页;
如果小于,则更新openid_time为当前时间,然后返回登录成功信息及手机号。
3. 登录页面:判断数据库中该手机号是否存在,如果存在,则更新openid_time为当前时间,如果不存在,则添加该手机号用户。然后跳转首页执行wx.login方法,登录成功,保持登陆状态。

详细流程:

步骤1:进入小程序首先通过wx.login获取code,通过后台接口发往后台,后台以此向微信API换取session_key和openid;

var user_phone = app.globalData.user_phone; wx.login({     success: res => {           // 发送 res.code 到后台换取 openId, sessionKey, unionId       wx.request({         url: 'http://www.tphoutai.com/wx/index',          data: {           code: res.code,           user_phone: user_phone,         },         success: function (result) {           var res = result.data;           console.log(res);                     if(res.sendsure == 0){             wx.reLaunch({               url: '../login/login',             })           }else if(res.sendsure == 1){             wx.reLaunch({               url: '../index/index',             })           }         }       })     }   })

步骤2:判断数据库中有无该openid【唯一标识,需和账号(手机号)绑定】;

// 后台代码: public function index(Request $request){         $url = "https://api.weixin.qq.com/sns/jscode2session";                 // 参数         $params['appid']= '小程序的appid';                 $params['secret']= '小程序的AppSecret';                 $params['js_code']= $request -> param('code');                 $params['grant_type']= 'authorization_code';                 $user_phone= $request -> param('user_phone');                 // 微信API返回的session_key 和 openid         $arr = httpCurl($url, $params, 'POST');                 $arr = json_decode($arr,true);                 // 判断是否成功         if(isset($arr['errcode']) && !empty($arr['errcode'])){                     return json(['code'=>'2','message'=>$arr['errmsg'],"result"=>null]);         }                 $openid = $arr['openid'];                 $session_key = $arr['session_key'];                 // 从数据库中查找是否有该openid         $is_openid = Db::table('user_info')->where('openid',$openid)->find();                 // 如果openid存在,更新openid_time,返回登录成功信息及手机号         if($is_openid){                     // openid存在,先判断openid_time,与现在的时间戳相比,如果相差大于4个小时,则则返回登录失败信息,使客户端跳转登录页,如果相差在四个小时之内,则更新openid_time,然后返回登录成功信息及手机号;             // 根据openid查询到所在条数据             $data = Db::table('user_info')->where('openid',$openid)->find();                         // 计算openid_time与现在时间的差值             $time = time() - $data['openid_time'];                         $time = $time / 3600;                         // 如果四个小时没更新过,则登陆态消失,返回失败,重新登录             if($time > 4){                             return json(['sendsure'=>'0','message'=>'登录失败',]);             }else{                             // 根据手机号更新openid时间                 $update = Db::table('user_info')->where('openid', $openid)->update(['openid_time' => time()]);                                 // 判断是否更新成功                 if($update){                                     return json(['sendsure'=>'1','message'=>'登录成功','user_phone' => $data['user_phone']]);                 }else{                                     return json(['sendsure'=>'0','message'=>'登录失败']);                 }             }                     // openid不存在时         }else{                     // dump($user_phone);             // 如果openid不存在, 判断手机号是否为空             if(isset($user_phone) && !empty($user_phone)){                             // 如果不为空,则说明是登录过的,就从数据库中找到手机号,然后绑定openid,+时间                  // 登录后,手机号不为空,则根据手机号更新openid和openid_time                 $update = Db::table('user_info')                     ->where('user_phone', $user_phone)                     ->update([                                             'openid'  => $openid,                                             'openid_time' => time(),                     ]);                                     if($update){                                         return json(['sendsure'=>'1','message'=>'登录成功',]);                 }             }else{                             // 如果也为空,则返回登录失败信息,使客户端跳转登录页                 return json(['sendsure'=>'0','message'=>'读取失败',]);             }         }     }

步骤3:登录页面:登录成功后,跳转首页执行wx.login方法,然后登录成功,保持登陆状态。

// 前台登录     wx.request({       url: 'http://www.tphoutai.com/wx/login',        data: {         user_phone: user_phone       },       success: function (result) {         var res = result.data;                 if (res.sendsure == 1){           app.globalData.user_phone = that.data.user_phone;           wx.reLaunch({             url: '../loading/loading',           })         }       }     })
// 后台登录方法     public function login(Request $request){          // 获取到前台传输的手机号         $user_phone = $request -> param('user_phone');                 // 判断数据库中该手机号是否存在         $is_user_phone = Db::table('user_info')->where('user_phone',$user_phone)->find();                 if(isset($is_user_phone) && !empty($is_user_phone)){                     // 登录时,数据库中存在该手机号,则更新openid_time             $update = Db::table('user_info')                     ->where('user_phone', $user_phone)                     ->update([                                             'openid_time' => time(),                     ]);                                 if($update){                                     return json(['sendsure'=>'1','message'=>'登录成功',]);             }         }else{                     $data = [                         "user_phone" => $user_phone,                         "pass" => '12345'             ];                         // 如果数据库中不存在该手机号,则进行添加             Db::table('user_info')->insert($data);         }        return json(['sendsure'=>'1','message'=>'登录成功',]);     }
根据微信API获取sessionkey 和 openid的方法
function httpCurl($url, $params, $method = 'GET', $header = array(), $multi = false){         date_default_timezone_set('PRC');                 $opts = array(             CURLOPT_TIMEOUT        => 30,             CURLOPT_RETURNTRANSFER => 1,             CURLOPT_SSL_VERIFYPEER => false,             CURLOPT_SSL_VERIFYHOST => false,             CURLOPT_HTTPHEADER     => $header,             CURLOPT_COOKIESESSION  => true,             CURLOPT_FOLLOWLOCATION => 1,             CURLOPT_COOKIE                      =>session_name().'='.session_id(),         );                 /* 根据请求类型设置特定参数 */         switch(strtoupper($method)){                     case 'GET':                         // $opts[CURLOPT_URL] = $url . '?' . http_build_query($params);                 // 链接后拼接参数  &  非?                 $opts[CURLOPT_URL] = $url . '?' . http_build_query($params);                break;            case 'POST':                //判断是否传输文件                 $params = $multi ? $params : http_build_query($params);                $opts[CURLOPT_URL] = $url;                $opts[CURLOPT_POST] = 1;                $opts[CURLOPT_POSTFIELDS] = $params;                break;            default:                throw new Exception('不支持的请求方式!');         }                 /* 初始化并执行curl请求 */         $ch = curl_init();         curl_setopt_array($ch, $opts);                 $data  = curl_exec($ch);                 $error = curl_error($ch);         curl_close($ch);                 if($error) throw new Exception('请求发生错误:' . $error);                 return  $data;     }

测试结果:
小程序和ThinkPHP5结合实现登录状态(附代码)

相关推荐:

thinkphp5中belongsToMany() 模块名称的命名问题解决

php中适配器模式的详细解析(附代码)

以上就是小程序和ThinkPHP5结合实现登录状态(附代码)的详细内容,更多请关注清酒竹杯其它相关文章!

  • 相关标签:
  • 本文原创发布清酒竹杯 ,转载请注明出处,感谢您的尊重!
  • 发表评论

    电子邮件地址不会被公开。 必填项已用*标注