Springboot网站第三方登录——QQ登录

这段时间为了做这几个第三方登录,走了很多弯路,跳了很多坑,为以后使用特地记录下来。

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

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

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

public abstract class DefaultAuthServiceImpl implements AuthService{public static RestTemplate getRestTemplate() {// 手动添加SimpleClientHttpRequestFactory requestFactory=new SimpleClientHttpRequestFactory();requestFactory.setReadTimeout(120000);List<HttpMessageConverter<?>> messageConverters = new LinkedList<>();messageConverters.add(new ByteArrayHttpMessageConverter());messageConverters.add(new StringHttpMessageConverter(StandardCharsets.UTF_8));messageConverters.add(new ResourceHttpMessageConverter());messageConverters.add(new SourceHttpMessageConverter<Source>());messageConverters.add(new AllEncompassingFormHttpMessageConverter());messageConverters.add(new MappingJackson2HttpMessageConverter());RestTemplate restTemplate=new RestTemplate(messageConverters);restTemplate.setRequestFactory(requestFactory);return restTemplate;}
}

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


QQ登录

1.首先去QQ互联注册一个账号,网站地址:https://connect.qq.com/,添加一个应用,具体怎么申请以及需要填写的信息,腾讯官网有详细文档。注册并完成相应信息填写后,可以在应用管理中查到应用的APP ID和APP Key。
2.QQ登录的后台代码如下:

步骤一:

创建一个继承AuthService的接口,QQAuthService,如下:
public interface QQAuthService extends AuthService {}

步骤二:

QQ登录的详细代码实现如下:
@Service
public class QQAuthServiceImpl extends DefaultAuthServiceImpl implements QQAuthService {private Logger logger = LoggerFactory.getLogger(QQAuthServiceImpl.class);//QQ 登陆页面的URLprivate final static String AUTHORIZATION_URL ="https://graph.qq.com/oauth2.0/authorize?response_type=code&client_id=%s&redirect_uri=%s&scope=%s";//获取token的URLprivate 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";// 获取用户 openid 的 URLprivate static final String OPEN_ID_URL = "https://graph.qq.com/oauth2.0/me?access_token=%s";// 获取用户信息的 URL,oauth_consumer_key 为 apiKeyprivate static final String USER_INFO_URL = "https://graph.qq.com/user/get_user_info?access_token=%s&oauth_consumer_key=%s&openid=%s";// 下面的属性可以通过配置读取private  static final String CALLBACK_URL = "http://XXX/XX/XX"; // QQ 在登陆成功后回调的 URL,这个 URL 必须在 QQ 互联里填写过private  static final String API_KEY  = "xxxxxx";                                      // QQ 互联应用管理中心的 APP IDprivate  static final String API_SECRET = "xxxxxx";               // QQ 互联应用管理中心的 APP Keyprivate  static final String SCOPE       = "get_user_info";                                  // QQ 互联的 API 接口,访问用户资料/*** @return QQ 登陆页面的 URL*/@Overridepublic String getAuthorizationUrl() {String url = String.format(AUTHORIZATION_URL,API_KEY,CALLBACK_URL,SCOPE);return url;}@Overridepublic String getAccessToken(String code) {String url = String.format(ACCESS_TOKEN_URL,API_KEY,API_SECRET,code, CALLBACK_URL);UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(url);URI uri = builder.build().encode().toUri();String resp = getRestTemplate().getForObject(uri, String.class);logger.error("getAccessToken resp = "+resp);if(resp.contains("access_token")){Map<String,String> map = getParam(resp);String access_token = map.get("access_token");return access_token;}else{throw new ServiceException(resp);}}//由于QQ的几个接口返回类型不一样,此处是获取key-value类型的参数private Map<String,String> getParam(String string){Map<String,String> map = new HashMap();String[] kvArray = string.split("&");for(int i = 0;i<kvArray.length;i++){String[] kv = kvArray[i].split("=");map.put(kv[0],kv[1]);}return map;}//QQ接口返回类型是text/plain,此处将其转为jsonpublic JSONObject ConvertToJson(String string){string = string.substring(string.indexOf("(")+1,string.length());string = string.substring(0,string.indexOf(")"));logger.error("ConvertToJson s = "+string);JSONObject jsonObject = JSONObject.parseObject(string);return jsonObject;}@Overridepublic String getOpenId(String accessToken) {String url = String.format(OPEN_ID_URL,accessToken);UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(url);URI uri = builder.build().encode().toUri();String resp = getRestTemplate().getForObject(uri, String.class);logger.error("getAccessToken resp = "+resp);if(resp.contains("openid")){JSONObject jsonObject = ConvertToJson(resp);String openid = jsonObject.getString("openid");return openid;}else{throw new ServiceException(resp);}}/*** https://graph.qq.com/user/get_user_info?access_token=YOUR_ACCESS_TOKEN&oauth_consumer_key=YOUR_APP_ID&openid=YOUR_OPENID* @param accessToken* @param openId* @return*/@Overridepublic JSONObject getUserInfo(String accessToken, String openId){openId = getOpenId(accessToken);String url = String.format(USER_INFO_URL,accessToken, API_KEY, openId);UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(url);URI uri = builder.build().encode().toUri();String resp = getRestTemplate().getForObject(uri,String.class);JSONObject data = JSONObject.parseObject(resp);logger.error("resp = "+data);JSONObject result = new JSONObject();result.put("id",openId);result.put("nickName",data.getString("nickname"));result.put("avatar",data.getString("figureurl_qq_1"));return result;}@Overridepublic String refreshToken(String code) {return null;}
}

步骤三:
在Controller中调用,代码如下:

@RestController
@RequestMapping(value = "/auth")
public class AuthController {private Logger logger = LoggerFactory.getLogger(AuthController.class);@Autowiredprivate QQAuthService qqAuthService;@Autowiredprivate UserService userService;//访问登陆页面,然后会跳转到 QQ 的登陆页面@RequestMapping(value = "/qqLoginPage",method = RequestMethod.GET)public JSONObject qqLogin() throws Exception {String uri = qqAuthService.getAuthorizationUrl();return loginPage(uri);}
}
//qq授权后会回调此方法,并将code传过来
@RequestMapping("/qq")public void getQQCode(String code, HttpServletRequest request,HttpServletResponse response) throws Exception {//根据code获取tokenString accessToken = qqAuthService.getAccessToken(code);// 保存 accessToken 到 cookie,过期时间为 30 天,便于以后使用Cookie cookie = new Cookie("accessToken", accessToken);cookie.setMaxAge(60 * 24 * 30);response.addCookie(cookie);//本网站是将用户的唯一标识存在用户表中,大家也可以加一张表,存储用户和QQ的对应信息。//根据openId判断用户是否已经绑定过String openId = qqAuthService.getOpenId(accessToken);KmsUser user = userService.getUserByCondition(openId);if (user == null) {//如果用户不存在,则跳转到绑定页面response.sendRedirect(request.getContextPath() + "/student/html/index.min.html#/bind?type="+Constants.LOGIN_TYPE_QQ);} else {//如果用户已存在,则直接登录response.sendRedirect(request.getContextPath() + "/student/html/index.min.html#/app/home?open_id=" + openId);}}

步骤四:
前台js中,先请求auth/qqLoginPage,获取授权地址,等用户授权后会回调/auth/qq,在此方法中进行逻辑处理即可。

Springboot网站第三方登录——QQ登录相关推荐

  1. 第三方平台授权登录— —QQ登录

    第三方平台授权登录- -QQ登录 本来前两天开开心心!心情乐乐!居然因为自己没有仔细看代码.居然被埋在这里两天!呜呜!怒火中烧!不行,我要去消灭 五碗大米饭 来平复我的心情! <程序运行图> ...

  2. 完整电商项目--(四)用户登录(4):第三方登录-QQ登录(续,关联网站账号)

    文章目录 上一节已经讲过了如何利用第三方QQ登录.下面讲下 绑定 网站账号的操作. (1)创建QQ模型类 具体接口业务流程: 下面就是视图了 注意:另外不能迷的是,一定要搞清楚,浏览器,QQ服务端,d ...

  3. 第三方登录 QQ登录(一) 申请接口

    申请QQ的第三方登录接口,你必须有一个在国内备案过的网站,个人的网站也可以. 1.成为开发者 进入QQ互联的官网:https://connect.qq.com,使用QQ登录. 登录之后点击右上角的头像 ...

  4. 【Spring Security OAuth2笔记系列】- Spring Social第三方登录 - QQ登录下

    qq登录下 前面把所有的代码组件都弄好了.现在可以开启调试了 在这之前你需要有一个qq互联的应用:也就是为了拿到appid和appSecret:自己去qq互联创建一个应用即可 这里讲下本地怎么调试应用 ...

  5. springboot项目功能之qq登录的实现

    思路 主要就是引入的了qq互联的api 要想调用qq登录的api首先要2个条件 有阿里云服务器 要申请一个域名,并且备案 有了这两个就可以在qq互联申请一个网站,会得到一个回调方法,然后qqAppId ...

  6. 美多商城之用户登录(QQ登录)

    二.QQ登录 2.1 QQ登录开发文档 QQ登录:即我们所说的第三方登录,是指用户可以不在本项目中输入密码,而直接通过第三方的验证,成功登录本项目. 1. QQ互联开发者申请步骤 若想实现QQ登录,需 ...

  7. Android 三方登录 - QQ登录

    由于项目需要三方登录,所以根据官方文档和一些其他资料,完成了一个Demo,这里记录一下. (1)申请腾讯开发者账号 到腾讯开发这平台(http://open.qq.com/)注册账号,很简单的. (2 ...

  8. java 模拟qq空间登陆_java最新完美实现模拟登录QQ登录QQ空间获取说说

    package com.pengliu.config; import com.pengliu.util.http.HttpService; /** * desc: 全局公共属性配置 */ public ...

  9. QQ自动登录/QQ登录器/程序源代码/VS2010/VS2012/VC/MFC

    学习豪迪,研究了一下QQ自动登录怎么写. 以前QQ登录的介面先用SPY++来找到QQ登陆框,然后再把密码copy进去,就可以了. 现在的QQ登录介面这招不行,用SPY++是找不到任何ID的. 怎办呢? ...

最新文章

  1. 2018/3/18 noip模拟赛 20分
  2. 黄聪: Bootstrap之Form表单验证神器: BootstrapValidator(转)
  3. 正则表达式的基本语法
  4. vue项目 :npm命令安装jquery
  5. 【LeetCode】 sort list 单清单归并
  6. 我是直接学Swift还是Objective-C?
  7. 蓝牙要抢ZigBee的地盘?低功耗广域网络笑了
  8. Cygwin用户改名、机器改名
  9. FleaPHP 1.0.70 开发进度汇报专贴
  10. 如何直接操作SVN将分支代码合并到主干
  11. 配置管理工具SVN的使用
  12. 苹果用计算机知道密码,苹果icloud密码忘了?最全攻略奉上
  13. win10系统安装virtualbox虚拟机win7系统过程记录
  14. Office EXCEL 创建图片超链接打不开怎么办 Excel打开图片提示发生了意外错误怎么办...
  15. STM32连接WIFI-ESP8266获取天气信息---STA模式运用
  16. Leecode101_isSymmetric
  17. 批量升级320k百度音乐(java版本)
  18. 用户登录、注册(基于MyBatis+CSS+HTML+Selvet)
  19. Jupyter Lab 密码登录、远程访问
  20. base64编码 vba_vb图片转base64编码

热门文章

  1. 以标记清除的方式垃圾回收
  2. 禁止 input 自动填充
  3. python TypeError: Descriptors cannot not be created directly错误解决
  4. 解决Swing控件setEnabled(false)时的字体颜色
  5. 怎样用excel剔除异常数据_excel如何去除异常值?(excel表格数据异常丢失)
  6. Magento前台不显示添加的产品
  7. mysql数据库的基本操作语句
  8. 药王修美乐黄金单品战法
  9. 这可能是最全的天气Api接口 (可在小程序中使用)
  10. NYOJ-845 无主之地1