最近在做个项目是基于微信的,所以去查看了微信开发文档。

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

1 第一步:用户同意授权,获取code

2 第二步:通过code换取网页授权access_token

3 第三步:刷新access_token(如果需要)

4 第四步:拉取用户信息(需scope为 snsapi_userinfo)

5 附:检验授权凭证(access_token)是否有效


  第一步:修改授权url:


https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect
其中将appid,direct_uri需要换成自己公众号的;
    direct_uri是授权后重定向的回调链接地址,请使用 urlEncode(转换,避免乱码,Java中是URLEncoder这个类)
对链接进行处理
    scope:应用授权作用域,snsapi_base(不弹出授权页面,直接跳转,只能获取用户openid),snsapi_userinfo
(弹出授权页面,可通过openid拿到昵称、性别、所在地。并且,即使在未关注的情况下,只要用户授权,也能获取其信息 )
    如果用户同意授权,页面将跳转至 redirect_uri/?code=CODE&state=STATE。
    code说明:code作为换取access_token的票据,每次用户授权带上的code将不一样,code只能使用一次,5分钟未被使用自动过期。

  第二步:通过code换取网页授权access_token
    
 这里通过code换取的是一个特殊的网页授权access_token,与基础支持中的access_token(该access_token用于调用其他接口)不同。公众号可通过下述接口来获取网页授权access_token。如果网页授权的作用域为snsapi_base,则本步骤中获取到网页授权access_token的同时,也获取到了openid,snsapi_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
      正确返回json格式数据为:
          {

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

   第三步:刷新access_token(如果需要)
       
 由于access_token拥有较短的有效期,当access_token超时后,可以使用refresh_token进行刷新,refresh_token有效期为30天,当refresh_token失效之后,需要用户重新授权。

         获取第二步的refresh_token后,请求以下链接获取access_token:

  https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=APPID&grant_type=refresh_token&refresh_token=REFRESH_TOKEN
 

第四步:拉取用户信息(需scope为 snsapi_userinfo)

如果网页授权作用域为snsapi_userinfo,则此时开发者可以通过access_token和openid拉取用户信息了。

请求方法:
http:GET(请使用https协议)
https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN
 

总而言之,就是先获取code,然后通过这个code去换取access_token
<https://mp.weixin.qq.com/wiki?action=doc&id=mp1421140842&t=0.13941878489806347&token=&lang=zh_CN#1>
,然后通过这个access_token
<https://mp.weixin.qq.com/wiki?action=doc&id=mp1421140842&t=0.13941878489806347&token=&lang=zh_CN#1>
就可以获取到用户的openId了。下面是基于Java的具体实现过程,有两种方式,第一种是手动获取openId,第二种是通过第三方sdk获取openId:

手动获取openId,将openid和SECRET换成自己对应的即可。:
@RestController @RequestMapping("/weixin") @Slf4j public class
WeiXinController { //微信授权认证登录 @GetMapping("/auth") public void
auth(@RequestParam("code") String code) { log.info("进入auth方法");
log.info("code={}", code); String url =
"https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code="+
code + "&grant_type=authorization_code"; // 调用rest服务,面向的是资源而不是面向服务,都是对应HTTP方法
// 这里的getForObject()是发送一个HTTP GET请求,返回的请求体将映射为一个对象 RestTemplate restTemplate =
new RestTemplate(); String response = restTemplate.getForObject(url,
String.class); log.info("response={}", response); } }
调用第三方sdk:

* 引入maven依赖 <!--sdk获取openid--> <dependency>
<groupId>com.github.binarywang</groupId>
<artifactId>weixin-java-mp</artifactId> <version>2.7.0</version> </dependency>
我这里用的springboot,所以需要在配置文件application.yml中加入appid和secret,然后再写一个类注入:
@Data @Component //注入application.yml中的属性,前缀为"wechat"
@ConfigurationProperties(prefix = "wechat") public class WeChatAccountConfig {
/** * 公众平台id */ private String mpAppId; /** * 公众平台密钥 */ private String
mpAppSecret; }
然后再通过第三方sdk提供的方法获取这些属性:
@Component public class WeChatMpConfig { // 注入appid和AppSecret @Autowired
private WeChatAccountConfig accountConfig; // @Bean主要用于方法上,表示将这个id注入到spring容器中
@Bean public WxMpService wxMpService() { WxMpService wxMpService = new
WxMpServiceImpl(); //获取注入的WxMpInMemoryConfigStorage的属性
wxMpService.setWxMpConfigStorage(wxMpConfigStorage()); return wxMpService; }
@Bean public WxMpConfigStorage wxMpConfigStorage() { WxMpInMemoryConfigStorage
wxMpConfigStorage = new WxMpInMemoryConfigStorage();
//获取注入的WeChatAccountConfig属性
wxMpConfigStorage.setAppId(accountConfig.getMpAppId());
wxMpConfigStorage.setSecret(accountConfig.getMpAppSecret()); return
wxMpConfigStorage; } }
这里贴一下几个用的方法,看到就可以懂了





最后是controller实现:
@Controller @RequestMapping("/wechat") @Slf4j public class WeChatController {
@Autowired private WxMpService wxMpService; @GetMapping("/authorize") //
传入一个回调url,后面可以实现重定向 public String authorize(@RequestParam("returnUrl") String
returnUrl) { //WxMpService wxMpService = new WxMpServiceImpl(); //1.配置 //2.调用方法
// 外网ip String url = 外网ip; // URLEncoder.encode设置转码,防止url乱码 String redirectUrl
= wxMpService.oauth2buildAuthorizationUrl(url, WxConsts.OAUTH2_SCOPE_BASE,
URLEncoder.encode(returnUrl)); log.info("【微信网页授权】获取code,result={}",
redirectUrl); return "redirect:" + redirectUrl; } //获取code,并交换AccessToken
@GetMapping("/userInfo") public String userInfo(@RequestParam("code") String
code, @RequestParam("state") String returnUrl) { WxMpOAuth2AccessToken
wxMpOAuth2AccessToken = new WxMpOAuth2AccessToken(); try {
wxMpOAuth2AccessToken = wxMpService.oauth2getAccessToken(code); } catch
(WxErrorException e) { log.error("【微信网页授权】{}", e); throw new
SellException(ResultEnum.WECHAT_MP_ERROR.getCode(),
e.getError().getErrorMsg()); } String openId =
wxMpOAuth2AccessToken.getOpenId(); return "redirect:" + returnUrl + "?openid="
+ openId; } }
同样,贴出部分源码:




友情链接
KaDraw流程图
API参考文档
OK工具箱
云服务器优惠
阿里云优惠券
腾讯云优惠券
华为云优惠券
站点信息
问题反馈
邮箱:[email protected]
QQ群:637538335
关注微信