第三方登录:QQ登录实现(OAuth2.0)

一、创建应用

1、在 QQ互联 创建应用

地址:https://connect.qq.com/manage.html#/

然后进行实名认证,创建应用,审核通过

然后点击查看,可以获得 APP ID 和 APP Key

回调地址如下

2、授权的基本原理

可以参考官方文档

1)根据QQ登录链接可以回调获得 code

2)根据APP ID 、APP Key 和 code 可获得 token

3)根据 token 获得 OpenId

4)  根据 OpenId 可以获得用户的基本信息

其中 OpenId 是一个唯一的值,比如 8A674574E1B12345D790A1B3EFE81234

3、几个必要的URL

1)登录页面授权 URL:

https://graph.qq.com/oauth2.0/authorize?response_type=code&client_id=%s&redirect_uri=%s&scope=%s

2)获得 Token 的 URL:

https://graph.qq.com/oauth2.0/token?grant_type=authorization_code&client_id=%s&client_secret=%s&code=%s&redirect_uri=%s

3)获得用户OpenId 的 URL:

https://graph.qq.com/oauth2.0/me?access_token=%s

4)获得用户信息的 URL:

https://graph.qq.com/user/get_user_info?access_token=%s&oauth_consumer_key=%s&openid=%s

二、基本准备

1、数据库设计

主要看 bind 和 bind_type 表的数据

identifier 表示识别码,保证唯一性

credential 表示凭证,通常用不上

bind_type_id 和 user_id 是外键,很好理解

name 唯一性

style 样式

2、放置 QQ 登录按钮

这里有两种常用的方式

① 弹小窗

  1. <script>
  2. function openWin(url,name,iWidth,iHeight) {
  3. //获得窗口的垂直位置
  4. var iTop = (window.screen.availHeight - 30 - iHeight) / 2;
  5. //获得窗口的水平位置
  6. var iLeft = (window.screen.availWidth - 10 - iWidth) / 2;
  7. window.open(url, name, ‘height=‘ + iHeight + ‘,innerHeight=‘ + iHeight + ‘,width=‘ + iWidth + ‘,innerWidth=‘ + iWidth + ‘,top=‘ + iTop + ‘,left=‘ + iLeft + ‘,status=no,toolbar=no,menubar=no,location=no,resizable=no,scrollbars=0,titlebar=no‘);
  8. }
  9. function qqLogin() {
  10. var url = "https://graph.qq.com/oauth2.0/authorize?response_type=code&client_id=101472393&redirect_uri=http://codergroup.cn/oauth/qq/callback&scope=get_user_info";
  11. openWin(url,"qqLogin",650,500);
  12. }
  13. </script>
  14. <a  href="javascript:void(0);" onclick="qqLogin()"></a>

② 在新窗口打开

  1. <a href="https://graph.qq.com/oauth2.0/authorizeresponse_type=code&client_id=101472393&redirect_uri=http://codergroup.cn/oauth/qq/callback&scope=get_user_info" target="_blank"></a>

三、具体代码

参考这里

1、由于做了多个登录,所以代码做了一定程度的封装,大致如下:

  1. //多个登录差不多都要共用这些方法,所以统一放到这个接口中
  2. public interface AuthService {
  3. public abstract String getAccessToken(String code);
  4. public abstract String getOpenId(String accessToken);
  5. public abstract String refreshToken(String code);
  6. public abstract String getAuthorizationUrl() throws UnsupportedEncodingException;
  7. public abstract JSONObject getUserInfo(String accessToken,String openId);
  8. }

2、由于全部是自己封装的,所以http请求的代码也是所有的登录共用的,这里统一放放到了类DefaultAuthServiceImpl中,代码如下:

  1. public abstract class DefaultAuthServiceImpl implements AuthService{
  2. public static RestTemplate getRestTemplate() {// 手动添加
  3. SimpleClientHttpRequestFactory requestFactory=new SimpleClientHttpRequestFactory();
  4. requestFactory.setReadTimeout(120000);
  5. List<HttpMessageConverter<?>> messageConverters = new LinkedList<>();
  6. messageConverters.add(new ByteArrayHttpMessageConverter());
  7. messageConverters.add(new StringHttpMessageConverter(StandardCharsets.UTF_8));
  8. messageConverters.add(new ResourceHttpMessageConverter());
  9. messageConverters.add(new SourceHttpMessageConverter<Source>());
  10. messageConverters.add(new AllEncompassingFormHttpMessageConverter());
  11. messageConverters.add(new MappingJackson2HttpMessageConverter());
  12. RestTemplate restTemplate=new RestTemplate(messageConverters);
  13. restTemplate.setRequestFactory(requestFactory);
  14. return restTemplate;
  15. }
  16. }

由此,所有的登录Service只需要继承AuthService即可。

3、QQ登录 Service 接口

QQAuthService.java

  1. public interface QQAuthService extends AuthService {
  2. }

4、QQ登录 Service 实现

QQAuthServiceImpl.java

  1. @Service
  2. public class QQAuthServiceImpl extends DefaultAuthServiceImpl implements QQAuthService {
  3. private Logger logger = LoggerFactory.getLogger(QQAuthServiceImpl.class);
  4. //QQ 登陆页面的URL
  5. private final static String AUTHORIZATION_URL =
  6. "https://graph.qq.com/oauth2.0/authorize?response_type=code&client_id=%s&redirect_uri=%s&scope=%s";
  7. //获取token的URL
  8. private final static String ACCESS_TOKEN_URL = "https://graph.qq.com/oauth2.0/token?grant_type=authorization_code&client_id=%s&client_secret=%s&code=%s&redirect_uri=%s";
  9. // 获取用户 openid 的 URL
  10. private static final String OPEN_ID_URL = "https://graph.qq.com/oauth2.0/me?access_token=%s";
  11. // 获取用户信息的 URL,oauth_consumer_key 为 apiKey
  12. private static final String USER_INFO_URL = "https://graph.qq.com/user/get_user_info?access_token=%s&oauth_consumer_key=%s&openid=%s";
  13. // 下面的属性可以通过配置读取
  14. private  static final String CALLBACK_URL = "http://XXX/XX/XX"; // QQ 在登陆成功后回调的 URL,这个 URL 必须在 QQ 互联里填写过
  15. private  static final String API_KEY  = "xxxxxx";                                      // QQ 互联应用管理中心的 APP ID
  16. private  static final String API_SECRET = "xxxxxx";               // QQ 互联应用管理中心的 APP Key
  17. private  static final String SCOPE       = "get_user_info";                                  // QQ 互联的 API 接口,访问用户资料
  18. /**
  19. * @return QQ 登陆页面的 URL
  20. */
  21. @Override
  22. public String getAuthorizationUrl() {
  23. String url = String.format(AUTHORIZATION_URL,API_KEY,CALLBACK_URL,SCOPE);
  24. return url;
  25. }
  26. @Override
  27. public String getAccessToken(String code) {
  28. String url = String.format(ACCESS_TOKEN_URL,API_KEY,API_SECRET,code, CALLBACK_URL);
  29. UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(url);
  30. URI uri = builder.build().encode().toUri();
  31. String resp = getRestTemplate().getForObject(uri, String.class);
  32. logger.error("getAccessToken resp = "+resp);
  33. if(resp.contains("access_token")){
  34. Map<String,String> map = getParam(resp);
  35. String access_token = map.get("access_token");
  36. return access_token;
  37. }else{
  38. throw new ServiceException(resp);
  39. }
  40. }
  41. //由于QQ的几个接口返回类型不一样,此处是获取key-value类型的参数
  42. private Map<String,String> getParam(String string){
  43. Map<String,String> map = new HashMap();
  44. String[] kvArray = string.split("&");
  45. for(int i = 0;i<kvArray.length;i++){
  46. String[] kv = kvArray[i].split("=");
  47. map.put(kv[0],kv[1]);
  48. }
  49. return map;
  50. }
  51. //QQ接口返回类型是text/plain,此处将其转为json
  52. public JSONObject ConvertToJson(String string){
  53. string = string.substring(string.indexOf("(")+1,string.length());
  54. string = string.substring(0,string.indexOf(")"));
  55. logger.error("ConvertToJson s = "+string);
  56. JSONObject jsonObject = JSONObject.parseObject(string);
  57. return jsonObject;
  58. }
  59. @Override
  60. public String getOpenId(String accessToken) {
  61. String url = String.format(OPEN_ID_URL,accessToken);
  62. UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(url);
  63. URI uri = builder.build().encode().toUri();
  64. String resp = getRestTemplate().getForObject(uri, String.class);
  65. logger.error("getAccessToken resp = "+resp);
  66. if(resp.contains("openid")){
  67. JSONObject jsonObject = ConvertToJson(resp);
  68. String openid = jsonObject.getString("openid");
  69. return openid;
  70. }else{
  71. throw new ServiceException(resp);
  72. }
  73. }
  74. /**
  75. * https://graph.qq.com/user/get_user_info?access_token=YOUR_ACCESS_TOKEN&oauth_consumer_key=YOUR_APP_ID&openid=YOUR_OPENID
  76. * @param accessToken
  77. * @param openId
  78. * @return
  79. */
  80. @Override
  81. public JSONObject getUserInfo(String accessToken, String openId){
  82. openId = getOpenId(accessToken);
  83. String url = String.format(USER_INFO_URL,accessToken, API_KEY, openId);
  84. UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(url);
  85. URI uri = builder.build().encode().toUri();
  86. String resp = getRestTemplate().getForObject(uri,String.class);
  87. JSONObject data = JSONObject.parseObject(resp);
  88. logger.error("resp = "+data);
  89. JSONObject result = new JSONObject();
  90. result.put("id",openId);
  91. result.put("nickName",data.getString("nickname"));
  92. result.put("avatar",data.getString("figureurl_qq_1"));
  93. return result;
  94. }
  95. @Override
  96. public String refreshToken(String code) {
  97. return null;
  98. }
  99. }

5、在Controller中调用,代码如下:

  1. @RestController
  2. @RequestMapping(value = "/oauth")
  3. public class AuthController {
  4. private Logger logger = LoggerFactory.getLogger(AuthController.class);
  5. @Autowired
  6. private QQAuthService qqAuthService;
  7. @Autowired
  8. private UserService userService;
  9. //访问登陆页面,然后会跳转到 QQ 的登陆页面
  10. @RequestMapping(value = "/qqLoginPage",method = RequestMethod.GET)
  11. public JSONObject qqLogin() throws Exception {
  12. String uri = qqAuthService.getAuthorizationUrl();
  13. return loginPage(uri);
  14. }
  15. }
  16. //qq授权后会回调此方法,并将code传过来
  17. @RequestMapping("/qq/callback")
  18. public void getQQCode(String code, HttpServletRequest request,HttpServletResponse response) throws Exception {
  19. //根据code获取token
  20. String accessToken = qqAuthService.getAccessToken(code);
  21. // 保存 accessToken 到 cookie,过期时间为 30 天,便于以后使用
  22. Cookie cookie = new Cookie("accessToken", accessToken);
  23. cookie.setMaxAge(60 * 24 * 30);
  24. response.addCookie(cookie);
  25. //本网站是将用户的唯一标识存在用户表中,大家也可以加一张表,存储用户和QQ的对应信息。
  26. //根据openId判断用户是否已经绑定过
  27. String openId = qqAuthService.getOpenId(accessToken);
  28. KmsUser user = userService.getUserByCondition(openId);
  29. if (user == null) {
  30. //如果用户不存在,则跳转到绑定页面
  31. response.sendRedirect(request.getContextPath() + "/bind?type="+Constants.LOGIN_TYPE_QQ);
  32. } else {
  33. //如果用户已存在,则直接登录
  34. response.sendRedirect(request.getContextPath());
  35. }
  36. }

查看更多

SpringBoot网站添加第三方登录之GitHub登录

本文转载自

原文作者:言曌博客

原文链接:https://liuyanzhao.com/8210.html

原文地址:https://www.cnblogs.com/xifengxiaoma/p/9508333.html

时间: 2024-11-03 21:32:07

第三方登录:QQ登录实现(OAuth2.0)的相关文章

第三方登录之QQ登录(二)——OAuth2.0处理流程介绍(以QQ登录为例)

为了让网站更快接入,腾讯提供了JS SDK的接入方案,具体点击这里或者点击这里进行查看. 不过也可以自己写代码,当然你需要了解QQ的OAuth2.0的处理流程(Web Server Flow). OAuth2.0的处理流程:点击这里查看官方Wiki. 1.授权:获取授权码Authorization Code 说明:第一步QQ必须得到要登录系统的授权信息,如果授权全成功,则会跳转到回调地址,同时授权码以参数形式,追加回调地址上. 当然还有一些其他参数,具体详情看官方介绍. 实例: https://

ThinkPHP第三方登录-QQ登录

参考:思梦教育 1.QQ互联(链接地址:https://connect.qq.com/index.html),进行开发者认证(未认证的情况下),有公司和个人两种认证方式,个人开发者选择个人认证就好,准备好身份证电子版.认证界面如图一,认证不做赘述. (图一) 2.认证通过界面如图二,认证完,我们将创建应用如图三,选择创建网站应用,填写好个人信息如图四. (图二) (图三) (图四) 3.应用创建好后,会有大约2天的认证时间,认证通过的情况下,可在应用管理下查看.成功创建的应用如图五 (图五) 4

网页应用接入第三方登录QQ登录,微信登录

注意:目前,很多应用都有安卓版,iOS版,还增加了网页版.这时,特别要注意,第三方数据的统一.所说的统一指的是用户在腾讯里的标识,一般原生应用会使用openid作为用户的唯一标识.这样做是错的,如果你要实现安卓,IOS与网页版数据统一就不能这样做.因为安卓,IOS与网页版的openid不一样!所以在开发前就要明确以后是否开发网页版和ios,安卓版. 1.如果开发这三种应用,而且要求数据统一,那么就该用unionid来作为用户唯一标识. 那么什么是unionid? 该接口用来获取用户的基本信息,开

php微信开放平台--第三方网页微信扫码登录(OAuth2.0)

第一.OAuth2.0 OAuth(开放授权)是一个开放标准,允许用户让第三方应用访问该用户在某一网站上存储的私密的资源(如照片,视频,联系人列表),而无需将用户名和密码提供给第三方应用. 允许用户提供一个令牌,而不是用户名和密码来访问他们存放在特定服务提供者的数据.每一个令牌授权一个特定的网站(例如,视频编辑网站)在特定的时段(例如,接下来的2小时内)内访问特定的资源(例如仅仅是某一相册中的视频).这样,OAuth允许用户授权第三方网站访问他们存储在另外的服务提供者上的信息,而不需要分享他们的

第三方登录(QQ登录)开发流程详解

原文  http://www.cnblogs.com/it-cen/p/4338202.html 主题 OpenID 近排由于工作的繁忙,已经一个星期没写博文做分享了,接下来我对网站接入第三方登录----QQ登录的实现逻辑做一个详细的讲解. 对于整个流程的详细文档可以到QQ互联官网( http://wiki.connect.qq.com )查看,我这里就简单地进行描述,主要是分析代码的实现过程. 我用的是CI框架(MVC模式),模板引擎用的是smarty. 下图为整个接入流程: 一.准备工作 接

(转)第三方登录(QQ登录)开发流程详解

近排由于工作的繁忙,已经一个星期没写博文做分享了,接下来我对网站接入第三方登录----QQ登录的实现逻辑做一个详细的讲解. 对于整个流程的详细文档可以到QQ互联官网(http://wiki.connect.qq.com)查看,我这里就简单地进行描述,主要是分析代码的实现过程. 我用的是CI框架(MVC模式),模板引擎用的是smarty. 下图为整个接入流程: 一.准备工作 接入QQ登录前,网站需首先进行申请,获得对应的appid与appkey,以保证后续流程中可正确对网站与用户进行验证与授权.

微信开放平台开发——网页微信扫码登录(OAuth2.0)

.OAuth2.0 OAuth(开放授权)是一个开放标准,允许用户让第三方应用访问该用户在某一网站上存储的私密的资源(如照片,视频,联系人列表),而无需将用户名和密码提供给第三方应用. 允许用户提供一个令牌,而不是用户名和密码来访问他们存放在特定服务提供者的数据.每一个令牌授权一个特定的网站(例如,视频编辑网站)在特定的时段(例如,接下来的2小时内)内访问特定的资源(例如仅仅是某一相册中的视频).这样,OAuth允许用户授权第三方网站访问他们存储在另外的服务提供者上的信息,而不需要分享他们的访问

网站集成QQ登录功能(转)

最近在做一个项目时,客户要求网站能够集成QQ登录的功能,以前没做过这方面的开发,于是去QQ的开放平台官网研究了一下相关资料,经过自己的艰苦探索,终于实现了集成QQ登录的功能,现在把相关的开发经验总结一下,希望对有这方面需求的朋友有所帮助. 一.前期准备 首先你需要登录QQ的开发平台注册一个账号,QQ互联平台官方地址:http://connect.qq.com/ 进去后注册一个开发账号,完了登录后台会有类似如下的一个后台,填好相关信息,具体可以参考下图.最后我们会有一个APP ID和APP KEY

网站集成QQ登录功能

最近在做一个项目时,客户要求网站能够集成QQ登录的功能,以前没做过这方面的开发,于是去QQ的开放平台官网研究了一下相关资料,经过自己的艰苦探索,终于实现了集成QQ登录的功能,现在把相关的开发经验总结一下,希望对有这方面需求的朋友有所帮助. 一.前期准备 首先你需要登录QQ的开发平台注册一个账号,QQ互联平台官方地址:http://connect.qq.com/ 进去后注册一个开发账号,完了登录后台会有类似如下的一个后台,填好相关信息,具体可以参考下图.最后我们会有一个APP ID和APP KEY

Spring Security 实战:QQ登录实现

准备工作 1.在 QQ互联 申请成为开发者,并创建应用,得到APP ID 和 APP Key.2.了解QQ登录时的 网站应用接入流程.(必须看完看懂) 为了方便各位测试,直接把我自己申请的贡献出来:APP ID : 101386962APP Key:2a0f820407df400b84a854d054be8b6a回调地址:http://www.ictgu.cn/login/qq 提醒:因为回调地址不是 http://localhost ,所以在启动我提供的demo时,需要在host文件中添加一行