Laravel——微信授权登陆

之前我没有做过微信开发之类,今天接触到了,来记录一下自己所理解的一些逻辑,首先,我画了一个草图,模拟逻辑.(示例代码在末尾)


官方文档https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140842


配合着开发文档看,开发文档写的非常详细的了。我这边记录学习,我我也把我看文档的一些逻辑分享出来:

一、关于网页授权回调域名的说明(节选了主要的部分,详细部分请查看官方文档)。

1. 在微信公众号求用之前,开者需要先到公众平台官网中的 - 接口 - - 页帐 - 权获取用基本信息的配置选项中,修改授域名。注意,里填写的是域名(是一个字符串),而不是URL,因此勿加 http:// 协议头

2.授权回调域名配置规范为全域名,比如需要网页授权的域名为:www.qq.com,配置以后此域名下面的页面,例:http://www.qq.com/music.htmlhttp://www.qq.com/login.html 都可以进行OAuth2.0鉴权。

二、关于网页授权的两种scope的区别说明

1、以snsapi_basescope发起的网页授权,是用来获取进入页面的用户的openid的,并且是静默授权并自动跳转到回调页的。用户感知的就是直接进入了回调页(往往是业务页面)

2、以snsapi_userinfoscope发起的网页授权,是用来获取用户的基本信息的。但这种授权需要用户手动同意,并且由于用户同意过,所以无须关注,就可在授权后获取该用户的基本信息。

3、用户管理类接口中的获取用户基本信息接口,是在用户和公众号产生消息交互或关注后事件推送后,才能根据用户OpenID来获取用户基本信息。这个接口,包括其他微信接口,都是需要该用户(即openid)关注了公众号后,才能调用成功的。


三、关于网页授权access_token和普通access_token的区别

1、微信网页授权是通过OAuth2.0机制实现的,在用户授权给公众号后,公众号可以获取到一个网页授权特有的接口调用凭证(网页授权access_token),通过网页授权access_token可以进行授权后接口调用,如获取用户基本信息;

2、其他微信接口,需要通过基础支持中的获取access_token”接口来获取到的普通access_token调用。

四、关于UnionID机制

1、请注意,网页授权获取用户基本信息也遵循UnionID机制。即如果开发者有在多个公众号,或在公众号、移动应用之间统一用户帐号的需求,需要前往微信开放平台(open.weixin.qq.com)绑定公众号后,才可利用UnionID机制来满足上述需求。

2UnionID机制的作用说明:如果开发者拥有多个移动应用、网站应用和公众帐号,可通过获取用户基本信息中的unionid来区分用户的唯一性,因为同一用户,对同一个微信开放平台下的不同应用(移动应用、网站应用和公众帐号),unionid是相同的。

五、关于特殊场景下的静默授权

1、上面已经提到,对于以snsapi_basescope的网页授权,就静默授权的,用户无感知;

2、对于已关注公众号的用户,如果用户从公众号的会话或者自定义菜单进入本公众号的网页授权页,即使是scopesnsapi_userinfo,也是静默授权,用户无感知。

具体而言,网页授权流程分为四步:

1、引导用户进入授权页面同意授权,获取code

2、通过code换取网页授权access_token(与基础支持中的access_token不同)

3、如果需要,开发者可以刷新网页授权access_token,避免过期

4、通过网页授权access_tokenopenid获取用户基本信息(支持UnionID机制)


接下来,我们来看具体的步骤:

  • 用户同意授权,获取code

就像我第一幅图中说的,weixin()方法中判断session中是否存在openid,如果没有存在,就去访问授权页面:

https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect 若提示该链接无法访问,请检查参数是否填写错误,是否拥有scope参数对应的授权作用域权限。

尤其注意:由于授操作安全等级较高,所以在起授权请,微信会权链接做正则强匹配校,如果接的参数序不,授权页面将无法正常访问

尤其注意:redirect_uri当使用https链接来确保授权code的安全性。





参数说明:

参数

是否必

  

appid

  公众号的唯一标识

redirect_uri

   

后重定向的回调链接地          址, 请使用 urlEncode 对链接进 行处

response_type

返回型,填写code

scope

应用授权作用域,snsapi_base (不出授权页面,直接跳,只能取用openid),snsapi_userinfo 出授权页面,可通openid拿到昵称、性、所在地。并且, 即使在未关注的情况下,只要用,也能取其信息

state

重定向后会state参数,开者可以填写a-zA-Z0-9的参数,最多128

#wechat_redirect

直接打开是做302重定向候,必须带此参数


如果用同意授面将跳 redirect_uri/?code=CODE&state=STATE


这里redirect_url 你在访问权页链接中的redirect_url参数。后面着code,你可以使用get方法得到。

code说明 code作为换取access_token的票据,每次用户授权带上的code将不一样,code只能使用一次,5分钟未被使用自动过期。


错误返回码说明如下:

返回

10003

redirect_uri域名与后台配置不一致

10004

此公众号被封禁

10005

此公众号并没有scope

10006

关注此测试

10009

操作太繁了,稍后重

10010

scope不能

10011

redirect_uri不能

10012

appid不能

10013

state不能

10015

公众号未授第三方平台,请检查

10016

不支持微信开放平台的Appid使用公众号Appid



  • 通过code换取网页授权圈的access_token .

网页授权之后,回调到你的回调地址并带参数code,在我第一幅图中,即为callback()方法,接下来的步骤就在这个方法中实现就可以了,那我们直接先获取参数code,然后再请求获取access_token

首先请注意,这里通过code换取的是一个特殊的网页授权access_token,与基础支持中的access_token(该access_token用于调用其他接口)不同。公众号可通过下述接口来获取网页授权access_token。如果网页授权的作用域为snsapi_base,则本步骤中获取到网页授权access_token的同时,也获取到了openidsnsapi_base式的网页授权流程即到此为止。

尤其注意:由于公众号的secret和获取到的access_token安全级别都非常高,必须只保存在服务器,不允许传给客户端。后续刷新access_token、通过access_token获取用户信息等步骤,也必须从服务器发起。

请求方法

获取code后,请求以下链接获取access_token  https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code

参数说明

参数

是否必

appid

公众号的唯一标识

secret

公众号的appsecret

code

填写第一步取的code参数

grant_type

填写authorization_code

返回说明

正确时返回的JSON数据包如下:

{ "access_token":"ACCESS_TOKEN",
"expires_in":7200,
"refresh_token":"REFRESH_TOKEN",
"openid":"OPENID",
"scope":"SCOPE" }

参数

描述

access_token

接口用凭,注意:此access_token与基支持的access_token不同

expires_in

access_token接口用凭时时间位(秒)

refresh_token

刷新access_token

openid

唯一标识注意,在未关注公众号,用户访问公众号的网,也会生一个用和公众号唯一的OpenID

scope

的作用域,使用逗号(,)分隔

错误时微信会返回JSON数据包如下(示例为Code无效错误):

{"errcode":40029,"errmsg":"invalid code"}


  • 获取用户信息(需scopesnsapi_userinfo

注:官方文档第三步为刷新access_token,因为他会过期,但是我们现在学习就不必用了,你可以先在官方文档上了解一下,写的也比较详细的了,今后有需要可以用上。


现在我们获取到了access_token,如何来获取用户的信息呢,当然还是请求地址啦!


请求方法

https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN

参数说明

参数

描述

access_token

接口用凭,注意:此access_token与基支持的access_token不同

openid

的唯一标识

lang

返回国家地区言版本,zh_CN 简体,zh_TW 繁体,en

返回说明

正确时返回的JSON数据包如下:

{    "openid":" OPENID",
" nickname": NICKNAME,
"sex":"1",
"province":"PROVINCE"
"city":"CITY",
"country":"COUNTRY",
"headimgurl":    "http://thirdwx.qlogo.cn/mmopen/g3MonUZtNHkdmzicIlibx6iaFqAc56vxLSUfpb6n5WKSYVY0ChQKkiaJSgQ1dZuTOgvLLrhJbERQQ4eMsv84eavHiaiceqxibJxCfHe/46",
"privilege":[ "PRIVILEGE1" "PRIVILEGE2"     ],
"unionid": "o6_bmasdasdsad6_2sgVt7hMZOPfL"
}

参数

描述

openid

的唯一标识

nickname

昵称

sex

的性值为1时是男性,值为2时是女性,值为0时是未

province

个人料填写的省份

city

普通用个人料填写的城市

country

国家,如中国CN

headimgurl

户头像,最后一个数代表正方形像大小(有04664961320代表640*640正方形像),用没有时该项为空。若用换头像,原有URL将失效。

privilege

信息,json ,如微信沃卡用户为chinaunicom

unionid

只有在用将公众号定到微信开放平台号后,才会出现该字段。

错误时微信会返回JSON数据包如下(示例为openid无效):

{"errcode":40003,"errmsg":" invalid openid "}


好了,获取到用户信息后,我们就把自己需要的信息存入到session中,这样,weixin()方法中判断的时候就会有信息啦,存入session后跳转到weixin()方法。现在session中有了openid,就不会在请求授权页面啦,直接获取session中的nickname然后输出到页面就可以啦!微信授权就到此就结束了。


还有需要注意的是,微信授权都是发请求,获取参数,但是,我们不能保证每次请求都能成功的。微信返回的数据不论成功还是失败,都是json数据的,所以,这个必须要注意的呀,实际开发中必须要记住的。


下面附上我的代码,一共两个页面,一个是视图页面(views)一个是控制器(controllers)控制器中有两个方法,也就是我文章头上所展示的图片,

我这边自己的appidsecret 隐藏掉了,这属于个人信息,每个公众号都是有的。


代码:

weixin.blade.php:

昵称:{{ $nickname }}

TestWeixinController.php:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

use App\Http\Requests;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Input;

class testWeixinController extends Controller
{

    public function weixin(Request $request)
    {
        //判断session中是否有openid,没有的话,跳转至微信授权页面,回掉方法callback中。
        if(!$request->session()->get('openid')){
            return redirect('https://open.weixin.qq.com/connect/oauth2/authorize?appid=$appid&redirect_uri=http://api.xiaoxxx.com/test/callback&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect');
        }
        //取出session中的nickname,返回到页面输出。
        $nickname = $request->session()->get('nickname');
        return view('weixin',[
            'nickname' => $nickname,
        ]);
    }

    public function callback(Request $request)
    {
        //回掉后获取微信授权生成的code
        $code  =  $request->get('code');
        //公众号的appid、secret
        $appId = "appid";
        $secret = "secret";
        //获取access_token的请求地址
        $url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=$appId&secret=$secret&code=$code&grant_type=authorization_code";
        //请求地址获取返回数据
        $weixin = file_get_contents($url);
        //因为返回的数据为json格式,需要json_decode
        $jsonDecode = json_decode($weixin);
        //json_decode后的参数为对象。获取需要的access_token、openid。
        $accessToken = $jsonDecode->access_token;
        $openId = $jsonDecode->openid;
        //根据access_token、openid去生成获取用户信息的地址
        $userInfoUrl = "https://api.weixin.qq.com/sns/userinfo?access_token=$accessToken&openid=$openId&lang=zh_CN";
        //请求地址,并获取相关参数
        $userInfoJson = file_get_contents($userInfoUrl);
        //因为返回的数据为json格式,需要json_decode
        $userInfoJsonDecode = json_decode($userInfoJson);
        //json_decode后的参数为对象。获取需要的openid、nickname。
        $openIdNew = $userInfoJsonDecode->openid;
        $nickName = $userInfoJsonDecode->nickname;
        //把openid、nickname存入session,方便weixin()方法能够调用
        $request->session()->put('openid', $openIdNew);
        $request->session()->put('nickname', $nickName);
        //返回weixin()方法
        return redirect('/test/weixin');
    }

}



猜你喜欢

转载自blog.csdn.net/weixin_41530218/article/details/80760665