下面是关于“SpringBoot集成QQ第三方登陆的实现”的完整攻略:
准备工作
获取QQ开放平台的App ID和App Secret
在访问QQ开放平台前,需要提前获取申请QQ第三方登陆的AppID和AppSecret,具体申请过程可以参考QQ互联官方文档。
导入依赖
在SpringBoot应用的pom.xml文件中添加QQ互联API的依赖,同时可以添加日志依赖:
<dependency>
<groupId>com.qq.connect</groupId>
<artifactId>qq-connect-sdk</artifactId>
<version>3.2.4</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
实现登陆逻辑
添加授权回调地址
在QQ互联开发平台上添加授权回调地址,这个地址是QQ登陆成功后返回的地址,QQ互联开发平台会根据这个地址重定向到我们的应用。
添加Controller处理授权回调请求
我们需要添加一个Controller来处理QQ登陆的授权回调请求,请求成功后,便可以获取到用户的openid。
@Controller
public class QQLoginController {
private final Logger logger = LogManager.getLogger(QQLoginController.class);
@Autowired
private QQConnectAPI qqConnectAPI;
@Autowired
private QQOAuth2AccessTokenDao qqOAuth2AccessTokenDao;
@GetMapping("/callback/qq")
public String handleCallback(HttpServletRequest request, HttpServletResponse response) {
// 获取登陆成功后的Token
try {
QQOAuth2AccessToken qqOAuth2AccessToken = qqConnectAPI.getAccessTokenByRequest(request);
// 写入session
request.getSession().setAttribute("accessToken", qqOAuth2AccessToken);
// 根据Token获取openid
String openId = qqConnectAPI.getOpenID(qqOAuth2AccessToken);
logger.debug("QQ用户授权成功,openid: " + openId);
// 重定向到首页
return "redirect:/";
} catch (QQConnectException e) {
logger.error("QQ用户授权失败,异常信息: " + e.getMessage(), e);
return null;
}
}
@GetMapping("/logout")
public String logout(HttpServletRequest request, HttpServletResponse response) {
// 获取Token
QQOAuth2AccessToken accessToken = (QQOAuth2AccessToken) request.getSession().getAttribute("accessToken");
if (accessToken != null) {
// 删除Token
qqOAuth2AccessTokenDao.deleteByAccessToken(accessToken.getAccessToken());
request.getSession().removeAttribute("accessToken");
logger.debug("QQ用户退出成功");
}
// 重定向到首页
return "redirect:/";
}
}
实现QQ登陆按钮
在页面添加QQ登陆按钮,点击按钮后跳转到QQ授权界面,界面中用户需要同意授权。
<a href="https://graph.qq.com/oauth2.0/authorize?response_type=code&client_id=你的App ID&redirect_uri=http://www.example.com/callback/qq&scope=get_user_info&state=test"><img src="http://qzonestyle.gtimg.cn/qzone/vas/opensns/res/img/Connect_logo_1.png" alt="QQ授权登陆"></a>
其中,client_id是我们注册应用时获得的appid,redirect_uri跳转回调地址,scope表示要获取的用户信息,state为业务状态标识。
实现获取QQ用户信息的逻辑
添加QQAPI调用
在我们的应用中添加QQAPI的调用,获取用户信息:
@Service
public class QQConnectService {
private final Logger logger = LogManager.getLogger(QQConnectService.class);
@Autowired
private QQConnectAPI qqConnectAPI;
public void getUserInfo(QQOAuth2AccessToken accessToken) throws QQConnectException {
QQUserInfo qqUserInfo = qqConnectAPI.getUserInfo(accessToken, "openid");
logger.debug("QQ用户信息获取成功,信息如下: " + qqUserInfo.toString());
}
}
添加用户信息获取逻辑
在一个Controller中添加查询用户信息的逻辑:
@Controller
public class UserController {
private final Logger logger = LogManager.getLogger(UserController.class);
@Autowired
private QQConnectService qqConnectService;
@GetMapping("/user")
public String getUser(HttpServletRequest request) {
// 获取用户Token
QQOAuth2AccessToken accessToken = (QQOAuth2AccessToken) request.getSession().getAttribute("accessToken");
if (accessToken == null) {
logger.debug("用户未登陆,需要先通过QQ授权登陆");
return "redirect:/";
}
try {
// 获取用户信息
qqConnectService.getUserInfo(accessToken);
return "user";
} catch (QQConnectException e) {
logger.error("获取QQ用户信息失败,异常信息: " + e.getMessage(), e);
return null;
}
}
}
当用户访问/user路由时,会通过Token获取QQ用户的openid,然后再通过openid获取用户的信息。
这里我们仅获取openid和用户的昵称,其他信息参照QQ官方API文档即可。
示例1:集成QQ登陆到SpringBoot应用
实现效果
这个示例实现的效果是:用户通过QQ授权登陆后,并可以通过用户信息页面获取用户的信息。
实现步骤
-
在QQ互联开放平台中注册应用,获取AppID和AppSecret。
-
添加QQAPI的依赖
在pom.xml文件中添加如下依赖:
<dependency>
<groupId>com.qq.connect</groupId>
<artifactId>qq-connect-sdk</artifactId>
<version>3.2.4</version>
</dependency>
- 实现登陆逻辑
这里我们只需要添加QQ登陆按钮和Controller处理授权回调即可。
- 实现获取QQ用户信息的逻辑
添加QQAPI调用,获取用户信息,并通过Controller查询用户信息。
具体代码可以参考上面的示例。
示例2:将QQ登陆集成到已有的用户系统中
实现效果
这个示例实现的效果是:将QQ登陆集成到已有的用户系统中,用户可以通过QQ授权登陆,登陆成功后也可以注销系统登陆。
实现步骤
- 在现有的系统上添加QQAPI的依赖
在pom.xml文件中添加如下依赖:
<dependency>
<groupId>com.qq.connect</groupId>
<artifactId>qq-connect-sdk</artifactId>
<version>3.2.4</version>
</dependency>
- 实现QQ授权登陆
这里我们需要添加QQ登陆按钮和Controller用于处理授权回调。
在登陆成功后,我们需要将用户的Token信息写入session,这个过程可以通过spring-session实现。
@Controller
public class QQLoginController {
// 省略其他代码
@GetMapping("/callback/qq")
public String handleCallback(HttpServletRequest request, HttpServletResponse response) {
// 获取登陆成功后的Token
try {
QQOAuth2AccessToken qqOAuth2AccessToken = qqConnectAPI.getAccessTokenByRequest(request);
// 写入session
request.getSession().setAttribute("accessToken", qqOAuth2AccessToken);
// 根据Token获取openid
String openId = qqConnectAPI.getOpenID(qqOAuth2AccessToken);
logger.debug("QQ用户授权成功,openid: " + openId);
// 将用户Token信息与现有系统中的用户账户进行绑定
// 这里我们假设用户UserCode就是openid
User user = userService.getByCode(openId);
if (user == null) {
// 如果现有系统中无此用户,则自动创建并关联
user = new User();
user.setCode(openId);
user.setName(qqConnectAPI.getUserInfo(qqOAuth2AccessToken, "nickname").getNickname());
userService.save(user);
}
// 绑定用户信息到session,以便于在系统中获取用户信息
request.getSession().setAttribute("userCode", user.getCode());
// 重定向到首页
return "redirect:/";
} catch (QQConnectException e) {
logger.error("QQ用户授权失败,异常信息: " + e.getMessage(), e);
return null;
}
}
}
- 用户信息的获取与注销
通过openid获取用户信息,以及注销token信息需要分别处理。
@Controller
public class UserController {
private final Logger logger = LogManager.getLogger(UserController.class);
@Autowired
private QQConnectService qqConnectService;
@Autowired
private QQOAuth2AccessTokenDao qqOAuth2AccessTokenDao;
@Autowired
private UserService userService;
@GetMapping("/user")
public String getUser(HttpServletRequest request) {
// 获取用户UserCode
String userCode = (String) request.getSession().getAttribute("userCode");
if (userCode == null) {
// 如果无登陆信息,返回首页
return "redirect:/";
}
// 获取QQ用户Token
QQOAuth2AccessToken accessToken = (QQOAuth2AccessToken) request.getSession().getAttribute("accessToken");
try {
User user = userService.getByCode(userCode);
// 获取用户个人信息
QQUserInfo qqUserInfo = qqConnectService.getUserInfo(accessToken);
user.setNickName(qqUserInfo.getNickname());
userService.update(user);
return "user";
} catch (QQConnectException e) {
logger.error("获取QQ用户信息失败,异常信息: " + e.getMessage(), e);
return null;
}
}
@GetMapping("/logout")
public String logout(HttpServletRequest request, HttpServletResponse response) {
// 获取Token
QQOAuth2AccessToken accessToken = (QQOAuth2AccessToken) request.getSession().getAttribute("accessToken");
if (accessToken != null) {
// 删除Token
qqOAuth2AccessTokenDao.deleteByAccessToken(accessToken.getAccessToken());
request.getSession().removeAttribute("accessToken");
logger.debug("QQ用户退出成功");
}
request.getSession().invalidate();
// 重定向到首页
return "redirect:/";
}
}
- 其他问题
在实际应用中,可能还需要解决在系统中已有用户授权登陆的问题,或者需要为授权登录的用户创建账号密码等其他信息。这些问题需要根据具体的业务需求进行分析和实现。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:SpringBoot集成QQ第三方登陆的实现 - Python技术站