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

本篇文章给大家带来的内容是关于小程序和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;

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

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【唯一标识,需和账号(手机号)绑定】;

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

// 后台代码:

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, 'GET');       

        $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方法,然后登录成功,保持登陆状态。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

// 前台登录

    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',

          })

        }

      }

    })

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

// 后台登录方法

    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的方法

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

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;

    }

转载于:https://www.cnblogs.com/niejunchan/p/10779249.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是使用ThinkPHP5实现用户注册、登录、验证的完整代码和数据库设计。 ## 数据库设计 ```sql CREATE TABLE `user` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT, `username` varchar(50) DEFAULT NULL COMMENT '用户名', `password` varchar(50) DEFAULT NULL COMMENT '密码', `email` varchar(50) DEFAULT NULL COMMENT '邮箱', `phone` varchar(20) DEFAULT NULL COMMENT '手机号码', `create_time` int(11) DEFAULT NULL COMMENT '创建时间', `update_time` int(11) DEFAULT NULL COMMENT '更新时间', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='用户表'; ``` ## 注册功能 ### 控制器代码 ```php namespace app\index\controller; use think\Controller; use think\Db; class Register extends Controller { public function index() { if (request()->isPost()) { // 获取表单数据 $data = input('post.'); // 验证用户名 if (empty($data['username'])) { $this->error('用户名不能为空'); } if (Db::name('user')->where('username', $data['username'])->find()) { $this->error('用户名已存在'); } // 验证密码 if (empty($data['password'])) { $this->error('密码不能为空'); } if ($data['password'] != $data['confirm_password']) { $this->error('两次密码输入不一致'); } // 验证邮箱 if (empty($data['email'])) { $this->error('邮箱不能为空'); } if (!filter_var($data['email'], FILTER_VALIDATE_EMAIL)) { $this->error('邮箱格式不正确'); } if (Db::name('user')->where('email', $data['email'])->find()) { $this->error('邮箱已存在'); } // 验证手机号码 if (empty($data['phone'])) { $this->error('手机号码不能为空'); } if (!preg_match('/^1[3456789]\d{9}$/', $data['phone'])) { $this->error('手机号码格式不正确'); } if (Db::name('user')->where('phone', $data['phone'])->find()) { $this->error('手机号码已存在'); } // 添加用户 $user = [ 'username' => $data['username'], 'password' => md5($data['password']), 'email' => $data['email'], 'phone' => $data['phone'], 'create_time' => time(), 'update_time' => time(), ]; if (Db::name('user')->insert($user)) { $this->success('注册成功', 'login/index'); } else { $this->error('注册失败'); } } return $this->fetch(); } } ``` ### 视图代码 ```html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>用户注册</title> </head> <body> <form method="post"> <div> <label for="username">用户名:</label> <input type="text" name="username" id="username"> </div> <div> <label for="password">密码:</label> <input type="password" name="password" id="password"> </div> <div> <label for="confirm_password">确认密码:</label> <input type="password" name="confirm_password" id="confirm_password"> </div> <div> <label for="email">邮箱:</label> <input type="email" name="email" id="email"> </div> <div> <label for="phone">手机号码:</label> <input type="text" name="phone" id="phone"> </div> <div> <button type="submit">注册</button> </div> </form> </body> </html> ``` ## 登录功能 ### 控制器代码 ```php namespace app\index\controller; use think\Controller; use think\Db; class Login extends Controller { public function index() { if (request()->isPost()) { // 获取表单数据 $data = input('post.'); // 验证用户名和密码 $user = Db::name('user')->where('username', $data['username'])->find(); if (!$user) { $this->error('用户名不存在'); } if (md5($data['password']) != $user['password']) { $this->error('密码不正确'); } // 记录登录状态 session('user', $user); $this->success('登录成功', 'index/index'); } return $this->fetch(); } public function logout() { // 销毁登录状态 session('user', null); $this->success('退出成功', 'login/index'); } } ``` ### 视图代码 ```html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>用户登录</title> </head> <body> <form method="post"> <div> <label for="username">用户名:</label> <input type="text" name="username" id="username"> </div> <div> <label for="password">密码:</label> <input type="password" name="password" id="password"> </div> <div> <button type="submit">登录</button> </div> </form> </body> </html> ``` ## 验证功能 ### 控制器代码 ```php namespace app\index\controller; use think\Controller; use think\Db; class Verify extends Controller { public function username() { $username = input('get.username'); if (Db::name('user')->where('username', $username)->find()) { return 'false'; } else { return 'true'; } } public function email() { $email = input('get.email'); if (!filter_var($email, FILTER_VALIDATE_EMAIL) || Db::name('user')->where('email', $email)->find()) { return 'false'; } else { return 'true'; } } public function phone() { $phone = input('get.phone'); if (!preg_match('/^1[3456789]\d{9}$/', $phone) || Db::name('user')->where('phone', $phone)->find()) { return 'false'; } else { return 'true'; } } } ``` ### 视图代码 ```html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>验证</title> </head> <body> <script src="/static/js/jquery.min.js"></script> <script> $(function () { $('#username').blur(function () { $.get('/index/verify/username', {username: $(this).val()}, function (data) { if (data == 'true') { $('#username_error').html(''); } else { $('#username_error').html('用户名已存在'); } }); }); $('#email').blur(function () { $.get('/index/verify/email', {email: $(this).val()}, function (data) { if (data == 'true') { $('#email_error').html(''); } else { $('#email_error').html('邮箱已存在或格式不正确'); } }); }); $('#phone').blur(function () { $.get('/index/verify/phone', {phone: $(this).val()}, function (data) { if (data == 'true') { $('#phone_error').html(''); } else { $('#phone_error').html('手机号码已存在或格式不正确'); } }); }); }); </script> <form> <div> <label for="username">用户名:</label> <input type="text" name="username" id="username"> <span id="username_error"></span> </div> <div> <label for="email">邮箱:</label> <input type="email" name="email" id="email"> <span id="email_error"></span> </div> <div> <label for="phone">手机号码:</label> <input type="text" name="phone" id="phone"> <span id="phone_error"></span> </div> </form> </body> </html> ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值