前后端分离获取微信网页授权

前后端分离获取微信网页授权

前端方法
function GetRequest()
		{
		    var url = location.search;   //获取url中"?"符后的字串   
		    var theRequest = new Object();
		    if (url.indexOf("?") != -1) 
		    {
		        var str = url.substr(1);
		        strs = str.split("&");
		        for (var i = 0; i < strs.length; i++) 
		        {
		            theRequest[strs[i].split("=")[0]] = unescape(strs[i].split("=")[1]);
		        }
		    }
		    return theRequest;
		}

		if (!GetRequest().call) {
			$.ajax({
			   	url: 'http://api.lejia.com/api/test',
			   	type: "GET",
			   	success: function (data) {
			   		console.log(data)
			   		window.location.href = data;
			   	},
			   	error: function(xhr){
			    	console.log(xhr)
			   	}
            });
		}else{
			eval(GetRequest().call);
		}

		function callback(){
			$.ajax({
			   	url: 'http://api.lejia.com/api/userList',
			   	type: "GET",
			   	success: function (data) {
			   		console.log(JSON.parse(data))
			   	},
			   	error: function(xhr){
			    	console.log(xhr)
			   	}
            });
			return false;
		}
  
index控制器
<?php
namespace app\api\controller;

use app\BaseController;
use lib\Character;
use think\facade\Db;
use think\Request;
use \Firebase\JWT\JWT;
use app\repository\WxService;

class Index
{
    public function test(request $request){
        $code = $request->param();

        error_reporting(1);
        header('Content-type:text/html; Charset=utf-8');
        $appid  = 'wxd4bcd8b1ab028596';
        $appKey = '7db30a7bd9750e3d4c1be405ea37b919';
        $wxPay  = new WxService($appid, $appKey);
        $data   = $wxPay->GetOpenid();
        redis()->hSet('wechat', 'data', json_encode($data, true));
        if (array_key_exists('code', $code)) {
            // 获取openid
            $wechatInfo = redis()->hGet('wechat', 'data');
            $wechatInfo = json_decode($wechatInfo);
            // 获取用户信息
            $user = $wxPay->getUserInfo($data['openid'], $data['access_token']);

            redis()->hSet('wechat', 'user', json_encode($user, true));
            // 获取回调域名
            $url = redis()->hGet('wechat', 'callback');

            redis()->hSet('wechat', 'Juser', $res);
            $url = $url.'?code='.$code['code'].'&state='.$code['state']."&call=callback()";
            return "<script>window.location.href = '{$url}'</script>";
            exit;
        }else{
            $url = getallheaders()['Referer'];
            redis()->hSet('wechat', 'callback', $url);
            redis()->hSet('wechat', 'url', json_encode($data, true));
            return json($data);
        }
    }
}
curl
function geturl($url){
        $headerArray =array("Content-type:application/json;","Accept:application/json");
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); 
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); 
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch,CURLOPT_HTTPHEADER,$headerArray);
        $output = curl_exec($ch);
        curl_close($ch);
        $output = json_decode($output,true);
        return $output;
    }

获取微信信息方法
<?php
namespace app\repository;

use think\facade\Db;

class WxService
{
    protected $appid;
    protected $appKey;

    public $data = null;

    public function __construct($appid, $appKey)
    {
        $this->appid  = $appid; //微信支付申请对应的公众号的APPID
        $this->appKey = $appKey; //微信支付申请对应的公众号的APP Key
    }

    /**
     * 通过跳转获取用户的openid,跳转流程如下:
     * 1、设置自己需要调回的url及其其他参数,跳转到微信服务器https://open.weixin.qq.com/connect/oauth2/authorize
     * 2、微信服务处理完成之后会跳转回用户redirect_uri地址,此时会带上一些参数,如:code
     *
     * @return 用户的openid
     */
    public function GetOpenid()
    {
        //通过code获得openid
        if (!isset($_GET['code'])) {
            //触发微信返回code码
            $baseUrl = $this->getCurrentUrl();
            $url     = $this->__CreateOauthUrlForCode($baseUrl);
            return $url;
            exit();
        } else {
            //获取code码,以获取openid
            $code   = $_GET['code'];
            $openid = $this->getOpenidFromMp($code);
            return $openid;
        }
    }

    public function getCurrentUrl()
    {
        $scheme = $_SERVER['HTTPS'] == 'on' ? 'https://' : 'http://';
        $uri    = $_SERVER['PHP_SELF'] . $_SERVER['QUERY_STRING'];
        if ($_SERVER['REQUEST_URI']) {
            $uri = $_SERVER['REQUEST_URI'];
        }

        $baseUrl = urlencode($scheme . $_SERVER['HTTP_HOST'] . $uri);
        return $baseUrl;
    }

    /**
     * 通过code从工作平台获取openid机器access_token
     * @param string $code 微信跳转回来带上的code
     * @return openid
     */
    public function GetOpenidFromMp($code)
    {
        $url        = $this->__CreateOauthUrlForOpenid($code);
        $res        = self::curlGet($url);
        $data       = json_decode($res, true);
        $this->data = $data;
        return $data;
    }

    /**
     * 构造获取open和access_toke的url地址
     * @param string $code,微信跳转带回的code
     * @return 请求的url
     */
    private function __CreateOauthUrlForOpenid($code)
    {
        $urlObj["appid"]      = $this->appid;
        $urlObj["secret"]     = $this->appKey;
        $urlObj["code"]       = $code;
        $urlObj["grant_type"] = "authorization_code";
        $bizString            = $this->ToUrlParams($urlObj);
        return "https://api.weixin.qq.com/sns/oauth2/access_token?" . $bizString;
    }

    /**
     * 构造获取code的url连接
     * @param string $redirectUrl 微信服务器回跳的url,需要url编码
     * @return 返回构造好的url
     */
    private function __CreateOauthUrlForCode($redirectUrl)
    {
        $urlObj["appid"]         = $this->appid;
        $urlObj["redirect_uri"]  = "$redirectUrl";
        $urlObj["response_type"] = "code";
        $urlObj["scope"]         = "snsapi_userinfo";
        $urlObj["state"]         = "STATE";
        $bizString               = $this->ToUrlParams($urlObj);
        return "https://open.weixin.qq.com/connect/oauth2/authorize?" . $bizString;
    }

    /**
     * 拼接签名字符串
     * @param array $urlObj
     * @return 返回已经拼接好的字符串
     */
    private function ToUrlParams($urlObj)
    {
        $buff = "";
        foreach ($urlObj as $k => $v) {
            if ($k != "sign") {
                $buff .= $k . "=" . $v . "&";
            }

        }
        $buff = trim($buff, "&");
        return $buff;
    }

    /**
     * 获取用户信息
     * @param string $openid 调用【网页授权获取用户信息】接口获取到用户在该公众号下的Openid
     * @return string
     */
    public function getUserInfo($openid, $access_token)
    {

        $response = self::curlGet('https://api.weixin.qq.com/sns/userinfo?access_token=' . $access_token . '&openid=' . $openid . '&lang=zh_CN');
        return json_decode($response, true);

    }

    public static function curlGet($url = '', $options = array())
    {
        $ch = curl_init($url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_TIMEOUT, 30);
        if (!empty($options)) {
            curl_setopt_array($ch, $options);
        }
        //https请求 不验证证书和host
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        $data = curl_exec($ch);
        curl_close($ch);
        return $data;
    }

    public static function curlPost($url = '', $postData = '', $options = array())
    {
        if (is_array($postData)) {
            $postData = http_build_query($postData);
        }
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
        curl_setopt($ch, CURLOPT_TIMEOUT, 30); //设置cURL允许执行的最长秒数
        if (!empty($options)) {
            curl_setopt_array($ch, $options);
        }
        //https请求 不验证证书和host
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        $data = curl_exec($ch);
        curl_close($ch);
        return $data;
    }
}


  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
实现微信扫码登录的前后端分离流程如下: 1. 前端生成登录二维码:前端页面加载时,向后端发送请求获取登录二维码的参数信息,包括appid和redirect_uri等,后端根据这些参数生成登录二维码的URL,并返回给前端。 2. 前端展示二维码:前端使用第三方库(如qrcode.js)将生成的登录二维码展示给用户。 3. 用户扫码确认登录:用户使用微信扫描前端展示的二维码,微信客户端会将用户的微信账号与该二维码关联,并向后端发送确认登录的请求。 4. 后端验证登录状态:后端接收到微信客户端发送的确认登录请求后,根据请求中的参数进行验证,包括校验appid、redirect_uri、code等信息的有效性。 5. 后端获取用户信息:验证通过后,后端使用code参数向微信服务器发送请求,获取用户的access_token和openid等信息。 6. 后端生成登录凭证:后端根据获取到的用户信息生成自己的登录凭证(如JWT),并将该凭证返回给前端。 7. 前端保存登录状态:前端接收到后端返回的登录凭证后,可以将该凭证保存在本地(如localStorage或cookie)用于后续的请求验证和会话管理。 8. 后续请求的验证:前后端分离后,后续的请求需要在请求头中携带登录凭证进行验证,后端根据凭证的有效性判断用户的登录状态。 这就是前后端分离实现微信扫码登录的大致流程,通过这种方式可以实现用户使用微信账号进行快速登录和注册。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值