基于Spring的微信第三方登录实现
2016-02-29 12:26
507 查看
在前几篇文章中,我们介绍了OAuth2.0认证和授权机制讲解,并实现了基于Spring的Github第三方登录--通用化的第三方登陆实现,之后,我们基于该通用化的框架,介绍了国内的两个比较流行的第三方登录平台:基于Spring的新浪微博第三方登录实现和基于Spring的QQ第三方登录实现。以上几个第三方登录平台都严格遵守了OAuth2.0协议。但是,近来作者发现微信的第三方登录确不是那么严格的遵守通用化的OAuth2.0协议,有些细节实现不太一样(例如获取AccessToken时其他OAuth平台用的字段名为client_id,但是微信中是appid),这就导致了之前的通用化框架在微信登录时遇到了很多问题,今天我们就来介绍一下微信的第三方登录,并重构一下我们的通用化框架,使之在遇到其他不那么严格遵守OAuth协议的平台依然简单实用。
接下来我们首先来看看如何在微信开放平台中申请一个第三方应用。
首先,我们需要完善开发者资质认证,在导航栏选择【账号中心】,然后选择【开发者资质认证】,我们会看到如下页面:
从页面信息介绍中的第二点我们可以知道,通过开发者资质认证后,我们就能够获得微信第三方登录的能力。需要注意:个人是不能申请第三方认证的,必须为以下机构或者团体才能进行认证,每次审核需要花费300元:
开发者资质认证提交并缴费后,会在两个工作日内进行审核,如果有问题会有客服人员电话沟通。
审核完成后,进入【管理中心】-> 【网站应用】。
点击【创建网站应用】,按照其提示填写相关内容即可:
提交完成后,如果你的开发者资质已经通过,就可以直接进行开发上线啦。现在,让我们看看如何添加微信第三方登录的代码。
现在,我们将基于Spring的Github第三方登录--通用化的第三方登陆实现中的通用化架构添加到代码中来,以此为基础添加微信登录的相关功能:
首先,让我们我们看看微信登录开发文档,看过之后,我们发现微信登录虽然是基于OAuth2.0协议,但是API的参数确不一样。之前我们做过github、微博、QQ其获取Access
Token时所需的参数为
但是微信中
但是
我们首先来添加一个接口
之后,我们将之前所有对
这样,我们对于第三方框架的重构就完成了。接下来我们来具体实现微信的第三方登录。
首先,添加WeixinApi,为OAuthService提供进行OAuth验证的各个地址,相关的地址可以在微信登录开发文档中得到,想了解微信第三方登录具体细节的同学可以仔细研读一下该文档。最终的WeixinApi代码如下:
最后是WeixinOAuthService的实现,除了CustomOAuthService的所定位的方法外,我们还需要重写
最后添加
与新浪微博一样,修改hosts一遍进行本地调试。
windows系统hosts文件一般在
mac系统hosts文件地址一般为:
在hosts文件添加以下一行:
进入根目录,运行
申请第三方应用
接下来我们首先来看看如何在微信开放平台中申请一个第三方应用。首先,我们需要完善开发者资质认证,在导航栏选择【账号中心】,然后选择【开发者资质认证】,我们会看到如下页面:
从页面信息介绍中的第二点我们可以知道,通过开发者资质认证后,我们就能够获得微信第三方登录的能力。需要注意:个人是不能申请第三方认证的,必须为以下机构或者团体才能进行认证,每次审核需要花费300元:
开发者资质认证提交并缴费后,会在两个工作日内进行审核,如果有问题会有客服人员电话沟通。
审核完成后,进入【管理中心】-> 【网站应用】。
点击【创建网站应用】,按照其提示填写相关内容即可:
提交完成后,如果你的开发者资质已经通过,就可以直接进行开发上线啦。现在,让我们看看如何添加微信第三方登录的代码。
第三方登录通用架构
现在,我们将基于Spring的Github第三方登录--通用化的第三方登陆实现中的通用化架构添加到代码中来,以此为基础添加微信登录的相关功能:
微信第三方登录服务分析
首先,让我们我们看看微信登录开发文档,看过之后,我们发现微信登录虽然是基于OAuth2.0协议,但是API的参数确不一样。之前我们做过github、微博、QQ其获取AccessToken时所需的参数为
client_id以及
client_secret,Scribe默认的OAuthService在处理也是同样的参数,因此我们可以通过其默认的
OAuth20ServiceImpl来处理OAuth的相关操作。
但是微信中
client_id、
client_secret两个参数统一用的是:
appid、
secret。这也就意味着我们需要实现自己的
WeixinOAuth20Service来对这些细节进行处理。同时,添加完成后,我们还需要添加一个
WeixinOAuthDeractorService来适配通用化的第三方登陆实现中的设计。
但是
WeixinOAuth20Service以及
WeixinOAuthDeractorService实际上功能是一样的,只是我们需要一个CustomOAuthService来对OAuthService进行管理。如果我们通过一个接口对OAuthService进行管理的话,我们就只需要添加一个类
WeixinOAuthService即可,同时这也符合依赖于接口而不是实现的最佳原则。
通过接口管理OAuthService
我们首先来添加一个接口CustomOAuthService:
public interface CustomOAuthService extends OAuthService{ String getoAuthType(); String getAuthorizationUrl(); OAuthUser getOAuthUser(Token accessToken); }
之后,我们将之前所有对
OAuthServiceDeractor修改为
CustomOAuthService:
@Service public class OAuthServices { @Autowired List<CustomOAuthService> oAuthServiceDeractors; public CustomOAuthService getOAuthService(String type){ Optional<CustomOAuthService> oAuthService = oAuthServiceDeractors.stream().filter(o -> o.getoAuthType().equals(type)) .findFirst(); if(oAuthService.isPresent()){ return oAuthService.get(); } return null; } public List<CustomOAuthService> getAllOAuthServices(){ return oAuthServiceDeractors; } }
这样,我们对于第三方框架的重构就完成了。接下来我们来具体实现微信的第三方登录。
WeixinApi
首先,添加WeixinApi,为OAuthService提供进行OAuth验证的各个地址,相关的地址可以在微信登录开发文档中得到,想了解微信第三方登录具体细节的同学可以仔细研读一下该文档。最终的WeixinApi代码如下:public class WeixinApi extends DefaultApi20 { private static final String AUTHORIZE_URL = "https://open.weixin.qq.com/connect/qrconnect?appid=%s&redirect_uri=%s&response_type=code&state=esfadsgsad34fwdef&scope=snsapi_login#wechat_redirect"; private static final String ACCESS_TOKEN_URL = "https://api.weixin.qq.com/sns/oauth2/access_token?grant_type=authorization_code"; @Override public String getAuthorizationUrl(OAuthConfig config) { return String.format(AUTHORIZE_URL, config.getApiKey(), OAuthEncoder.encode(config.getCallback())); } @Override public String getAccessTokenEndpoint() { return ACCESS_TOKEN_URL; } @Override public OAuthService createService(OAuthConfig config){ return new WeixinOAuthService(this, config); } }
WeixinOAuthService
最后是WeixinOAuthService的实现,除了CustomOAuthService的所定位的方法外,我们还需要重写getAccessToken:
public class WeixinOAuthService extends OAuth20ServiceImpl implements CustomOAuthService { private final DefaultApi20 api; private final OAuthConfig config; private final String authorizationUrl; public WeixinOAuthService(DefaultApi20 api, OAuthConfig config) { super(api, config); this.api = api; this.config = config; this.authorizationUrl = getAuthorizationUrl(null); } @Override public Token getAccessToken(Token requestToken, Verifier verifier){ OAuthRequest request = new OAuthRequest(api.getAccessTokenVerb(), api.getAccessTokenEndpoint()); request.addQuerystringParameter("appid", config.getApiKey()); request.addQuerystringParameter("secret", config.getApiSecret()); request.addQuerystringParameter(OAuthConstants.CODE, verifier.getValue()); if(config.hasScope()) request.addQuerystringParameter(OAuthConstants.SCOPE, config.getScope()); Response response = request.send(); String responceBody = response.getBody(); Object result = JSON.parse(responceBody); return new Token(JSONPath.eval(result, "$.access_token").toString(), "", responceBody); } @Override public OAuthUser getOAuthUser(Token accessToken) { OAuthUser oAuthUser = new OAuthUser(); oAuthUser.setoAuthType(getoAuthType()); Object result = JSON.parse(accessToken.getRawResponse()); oAuthUser.setoAuthId(JSONPath.eval(result, "$.openid").toString()); oAuthUser.setUser(new User()); return oAuthUser; } @Override public String getoAuthType() { return OAuthTypes.WEIXIN; } @Override public String getAuthorizationUrl() { return authorizationUrl; } }
配置WeixinOAuthService
最后添加WeixinOAuthService的相关配置:
@Configuration public class OAuthConfig { private static final String CALLBACK_URL = "http://tianmaying.com/oauth/%s/callback"; @Value("${oAuth.weixin.appId}") String weixinAppId; @Value("${oAuth.weixin.appSecret}") String weixinAppSecret; @Bean public CustomOAuthService getSinaOAuthService(){ return (CustomOAuthService) new ServiceBuilder() .provider(WeixinApi.class) .apiKey(weixinAppId) .apiSecret(weixinAppSecret) .scope("snsapi_login") .callback(String.format(CALLBACK_URL, OAuthTypes.WEIXIN)) .build(); } }
修改hosts
与新浪微博一样,修改hosts一遍进行本地调试。windows系统hosts文件一般在
C:\WINDOWS\system32\drivers\etc
mac系统hosts文件地址一般为:
/etc/hosts
在hosts文件添加以下一行:
127.0.0.1 tianmaying.com
调试
进入根目录,运行sudo mvn spring-boot:run命令,访问http://tianmaying.com (之前填写应用信息以及修改hosts时所填写的域名,这三个域名必须一致),由于必须通过域名进行访问,所以我们需要监听80端口,运行时需要超级管理员权限。
相关文章推荐
- java 各种加密算法
- 深入Java集合学习系列:HashMap的实现原理
- 基于Spring的Github第三方登录--通用化的第三方登陆实现
- [Java 并发] Java并发编程实践 思维导图 - 第一章 简单介绍
- Java语言中自动生成随机数
- struts2 2.3.15升级到2.3.24.1问题
- java动态导出excel压缩成zip下载
- 2015年33期Java/Spring/Struts2/web/基础/就业班视频
- 2015年33期Java/Spring/Struts2/web/基础/就业班视频
- 详解Java GC的工作原理
- Java堆内存
- Java堆内存
- Java编程中“为了性能”需做的26件事
- Spring MVC and Maven – first project: Hello world! Basic template
- 2015 java 第168期全套包含springmvc mybatis shiro视频教程
- eclipse下NDK生成.SO文件
- 2015 java 第168期全套包含springmvc mybatis shiro视频教程
- Spring MVC防止数据重复提交
- java学习—null和isEmpty 区别
- java中length,length(),size()区别