code换取微信openid_微信授权登录开发的两种方式

本文主要针对微信公众号(公众平台的开发)

首先理解一个概念:OAuth:

OAuth(开放授权)是一个开放标准,允许用户让第三方应用访问该用户在某一网站上存储的私密的资源(如照片,视频,联系人列表),而无需将用户名和密码提供给第三方应用。

在本篇文章中模拟用户在微信公众号中使用OAuth进行授权,从而使第三方应用拿到用户的部分信息。

详细的开发文档可查看微信的官方文档 https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/Wechat_webpage_authorization.html

首先由于本人没有企业级微信公众账号,所以利用个人微信申请了微信公众账号的一个测试号,申请步骤如下:

进入测试号之后,系统会分配一个appleID和appsecret(可以用于在开发项目的yml文件中配置)

99a82386e7fe03af2b057c41764adc3a.png

接着需要配置接口信息,由于微信开发需要公网才能被访问到,因此需要将内网穿透到外网才能保证接口可访问性。

natapp地址:

NATAPP -​natapp.cn
68c0433728629cce316d7fb137425255.png

由于免费隧道每次映射的ip会发生变化,所以建议购买VIP隧道(大概加上二级域名12元/月?)买完之后你会拿到一个authtoken。

然后下载natapp文件,使用终端cd到natapp所在的文件夹下,利用:

#进行授权操作
$ chmod a+x natapp
# 在natapp文件的当前路径运行
$ ./natapp -authtoken={此处填写authtoken值}

显示如下则配置成功:

086d82272ae68d328a0bdc59bf295c98.png

这样以后就可以继续配置测试号中的接口了,现在来说说接口信息中的URL和token到底是什么。

简单地说就是微信测试号需要通过请求一个URL来相应token验证,也就是说你在点击确定时向你指定的URL发送一个请求,在请求里面来验证你的token是否一致。完成此验证之后,微信才能进行调用这个外网服务器端口。所以需要编写一个借口放在服务器上面:

SpringBoot代码如下:

@RequestMapping("/wechat")
@Controller
public class TestnatappController {
    private static Logger logger = Logger.getLogger(TestnatappController.class);

    private static String WECHAT_TOKEN = "DQicy";

    @RequestMapping(value = "/wx.do")
    public void get(HttpServletRequest request, HttpServletResponse response) throws Exception {

        logger.error("WechatController   ----   WechatController");

        System.out.println("========WechatController========= ");
        logger.info("请求进来了...");

        Enumeration pNames = request.getParameterNames();
        while (pNames.hasMoreElements()) {
            String name = (String) pNames.nextElement();
            String value = request.getParameter(name);
            // out.print(name + "=" + value);

            String log = "name =" + name + "     value =" + value;
            logger.error(log);
        }

        String signature = request.getParameter("signature");/// 微信加密签名
        String timestamp = request.getParameter("timestamp");/// 时间戳
        String nonce = request.getParameter("nonce"); /// 随机数
        String echostr = request.getParameter("echostr"); // 随机字符串
        PrintWriter out = response.getWriter();

        //if (SignUtil.checkSignature(signature, timestamp, nonce)) {
        out.print(echostr);
//		}s
        out.close();
//		out = null;

    }
}

注意将程序中的token换成和你想要配置的token一致即可。然后url就可以写成你原先配置的外网/wechat/wx.do的形式,即可验证通过。

继续配置回调函数:

9fca6388eb3b471f53e54a99cc21981b.png

回调函数用于当我们在微信客户端访问第三方应用的时候,首先通过微信网页授权机制获取到用户授权的信息后,通过回调的域名设置,页面还会进行再次跳转。所以配置为外网即可(注意去掉协议部分,即http://)。如果你的网址没有被列入黑名单,就会通过安全监测,就可以使用啦。

至此,域名的配置成功了。

然后进入授权部分,先看官方文档怎么说:

5b0649d9e32039e81dcebb6304edc20b.png

两种方法:

1.手工获取openid

首先第一步:引导关注者打开https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect

其中appid替换为自己的标识信息,

redirect_uri填上要跳转的连接,

scope是应用授权的作用域,有两种选择(根据不同需要作出不同选择):

(1)snsapi_base:这种方式可以直接获取用户的少量信息,不弹出授权的页面

(2)snsapi_userinfo: 这种方式需要用户点击确认按键,但是可以通过openid拿到更多用户的信息

response_type设置为code即可。

如果用户同意授权,页面将跳转至 redirect_uri/?code=CODE&state=STATE。也就是说返回的url中会拿到code值,于是在项目中补上controller来接收用户的code值(code值有效期只有5分钟)

控制器代码如下:

package com.imooc.controller;
@RestController
@RequestMapping("/weixin")
@Slf4j
public class WeixinController {
    @GetMapping("/auth")
    public void auth(@RequestParam("code") String code) {
        log.info("进入auth方法...");
        log.info("code={}", code);
    }
}

在auth方法中接收url返回的code值通过手机测试,可以在console输出code的值。

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

36fc52f86419d3734a7af8ae93b7e7e6.png

f4a91e8648ee120d182d6218af836001.png

根据官方说明,用code换取access_token的过程实际上是返回一个json格式的数据。

接着测试:

       String url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=wx45ea7710b15596a9&secret=0dffebbdf4591d3de7f76ebc08d5f13d&code=" + code + "&grant_type=authorization_code";
        RestTemplate restTemplate = new RestTemplate();
        String response = restTemplate.getForObject(url,String.class);
        log.info("response={}",response);

response即为包含access_token的json数据,其中包含后面会用到的openid。

2.利用第三方SDK

github地址:

https://github.com/Pay-Group/best-pay-sdk​github.com

用之前先在pom.xml中引入依赖,再看网页授权部分的操作:

https://github.com/Wechat-Group/WxJava/wiki/MP_OAuth2%E7%BD%91%E9%A1%B5%E6%8E%88%E6%9D%83​github.com

首先配置WxService:

@Data
@Component
//下面注解的作用:spring-boot 提供该注解将配置文件的值映射到类上使用
@ConfigurationProperties(prefix = "wechat")
public class WechatAccountConfig {
    //公众平台Id
    private String mpAppId;
    //公众平台密钥
    private String mpAppSecret;
}

在MpConfig文件中引用配置的account:

@Component
public class WechatMpConfig {

    @Autowired
    private WechatAccountConfig accountConfig;

    @Bean
    public WxMpService wxMpService(){
        WxMpService wxMpService = new WxMpServiceImpl();
        wxMpService.setWxMpConfigStorage(wxMpConfigStorage());
        return wxMpService;
    }

    @Bean
    public WxMpConfigStorage wxMpConfigStorage() {
        WxMpInMemoryConfigStorage wxMpConfigStorage = new WxMpInMemoryConfigStorage();
        wxMpConfigStorage.setAppId(accountConfig.getMpAppId());
        wxMpConfigStorage.setSecret(accountConfig.getMpAppSecret());
        return wxMpConfigStorage;
    }
}


然后写控制器类:

@Controller
@RequestMapping("/wechat")
@Slf4j
public class WechatController {
    @Autowired
    private WxMpService wxMpService;

    @GetMapping("/authorize")
    public String authorize(@RequestParam("returnUrl") String returnUrl){
        //1.配置
        //2.调用方法 (重定向)
        String url = "http://.../sell/wechat/userInfo";
        String redirectUrl = wxMpService.oauth2buildAuthorizationUrl(url,WxConsts.OAUTH2_SCOPE_BASE, URLEncoder.encode(returnUrl));
        log.info("[微信网页授权] 获得code, result={}", redirectUrl);
        return "redirect:" + redirectUrl ;
    }
    //下面为重定向后到达的方法
    @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());
       }
        return "redirect:" + returnUrl + "?openid=" + openId;
    }

}

通过获取code,再通过获取access_token的方式即可获得用户的openid。

以上为两种微信授权登录的常用方式。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值