作者:人間蒸發
來源:zuidaima.com/blog/4725615031700480.htm
QQ互聯註冊一個帳號網站地址:https://connect.qq.com/,添加一個應用,具體怎麼申請以及需要填寫的信息,騰訊官網有詳細文檔。註冊並完成相應信息填寫後,可以在應用管理中查到應用的APP ID和APP Key。
成功後如下圖:
還需要添加一個回調地址,如下圖:
加入jar包<!-- 第三方QQ登錄 -->
<dependency>
<groupId>com.qq</groupId>
<artifactId>Sdk4J</artifactId>
<version>2</version>
</dependency>登錄頁面
<button type="submit" class="btn btn-default" onclick="qqLogin()">qq登錄</button>
function qqLogin() {
window.open("/login/qqLogin","TencentLogin");
}Controller編寫
package com.gbq.boot.web.controller;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.gbq.boot.web.bean.User;
import com.gbq.boot.web.comment.qqLoginComment.AuthComment;
import com.gbq.boot.web.service.UserService;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
/**
* 登錄Controller
* @author 阿前
* 2019年1月4日09:48:21
*/
@RestController
@RequestMapping("/login")
public class LoginController {
@Resource
private UserService userService;
@Resource
private AuthComment authComment;
@RequestMapping("/index")
public ModelAndView index(@ModelAttribute("user") User user) {
return new ModelAndView("/shop/index","user",user);
}
@RequestMapping("/login.html")
public ModelAndView toLogin() {
return new ModelAndView("login");
}
@RequestMapping("/qqLogin")
public void qqLogin(HttpServletResponse response)throws Exception{
//隨機產生字符串
String state = StrUtil.uuid();
String url = authComment.getAuthUrl(state);
System.out.println(url);
//重定向
response.sendRedirect(url);
}
@GetMapping("/redirect")
public ModelAndView getData(@RequestParam(value = "code") String code, RedirectAttributes model){
//獲取token
String accessToken = authComment.getAccessToken(code);
System.out.println("accessToken"+accessToken);
//獲取openId
String openId = authComment.getOpenId(accessToken);
System.out.println("openId"+openId);
//獲取用戶信息
JSONObject userInfo = authComment.getUserInfo(accessToken, openId);
String myName = userInfo.getString("nickname");
User user = new User(null, "","111111",myName, System.currentTimeMillis(),"是",
userInfo.getString("figureurl_2"), userInfo.getString("gender")
,1,1,"", "", openId);
//通過openId查詢
User usr = userService.findUsrByOpenId(openId);
if (null != usr){
user.setId(usr.getId());
userService.updateById(user);
}else {
userService.insert(user);
}
model.addFlashAttribute("user", user);
//重定向
return new ModelAndView("redirect:/login/index");
}
}AuthComment類編寫
package com.gbq.boot.web.comment.qqLoginComment;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static org.apache.commons.io.IOUtils.toByteArray;
@Component
public class AuthComment {
//QQ 登陸頁面的URL
private final static String AUTHORIZATION_URL =
"https://graph.qq.com/oauth2.0/authorize?response_type=code&client_id=%s&redirect_uri=%s&scope=%s";
//獲取token的URL
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";
// 獲取用戶 openid 的 URL
private static final String OPEN_ID_URL = "https://graph.qq.com/oauth2.0/me?access_token=%s";
// 獲取用戶信息的 URL,oauth_consumer_key 為 apiKey
private static final String USER_INFO_URL = "https://graph.qq.com/user/get_user_info?access_token=%s&oauth_consumer_key=%s&openid=%s";
// 下面的屬性可以通過配置讀取
// QQ 在登陸成功後回調的 URL,這個 URL 必須在 QQ 互聯裡填寫過
private static final String CALLBACK_URL = "http://127.0.0.1:8080/login/redirect";
// QQ 互聯應用管理中心的 APP ID
private static final String APP_ID = "你的id";
// QQ 互聯應用管理中心的 APP Key
private static final String APP_SECRET = "你的key";
/**
* QQ 登陸頁面的URL
* @param scope
* @return
*/
public String getAuthUrl(String scope) {
return String.format(AUTHORIZATION_URL, APP_ID, CALLBACK_URL, scope);
}
/**
* 獲取Access Token值
*/
public String getAccessToken(String code){
String ur = String.format(ACCESS_TOKEN_URL, APP_ID, APP_SECRET,code, CALLBACK_URL);
String compile = "access_token=(\\w*)&";
String result = this.getUrl(ur);
return this.getMatcher(result,compile);
}
/**
* 獲取openId
* @param accessToken
* @return
*/
public String getOpenId(String accessToken) {
String url = String.format(OPEN_ID_URL, accessToken);
String compile = "openid\":\"(\\w*)\"";
String result = this.getUrl(url);
return this.getMatcher(result,compile);
}
/**
* 獲取qq用戶信息
* @param accessToken
* @param openId
* @return
*/
public JSONObject getUserInfo(String accessToken, String openId) {
String url = String.format(USER_INFO_URL, accessToken, APP_ID, openId);
String result = this.getUrl(url);
return JSON.parseObject(result);
}
private String getMatcher(String result,String compile) {
//使用正則表達式解析網址
Pattern p = Pattern.compile(compile);
Matcher m = p.matcher(result);
m.find();
return m.group(1);
}
//解析url
private String getUrl(String ur) {
try {
URL url = new URL(ur);
HttpURLConnection conn = null;
conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(5 * 1000);
conn.setRequestMethod("GET");
InputStream inStream = conn.getInputStream();
byte[] data = toByteArray(inStream);
String result = new String(data, "UTF-8");
System.out.println(result);
return result;
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}此處不再編寫userService
成功會返回json串
其中主要需要的是,nickname——qq名稱,figureurl_qq_x——不同尺寸的qq頭像,等等等等!
登錄成功跳轉到頁面
成功後的頁面index
注意我使用的是freemarker模板,給大家貼上freemarker配置,已經mvc配置
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>freemarker:
template-loader-path: classpath:/templates/
# 是否啟用模板緩存。
suffix: .ftl
cache: false
# 模板編碼。
charset: UTF-8
# 是否檢查模板位置是否存在。
check-template-location: true
content-type: text/html
#是否啟用freemarker
enabled: true
mvc:
view:
prefix: /templates/
suffix: .html
static-path-pattern: /static/**