【SpringSecurity+OAuth2+JWT入门到实战】16.第三方登录绑定和解绑
读取用户第三方登录详细源码分析
SpringSocial已经未我们提供了方法ConnectController来读取以后第三方登录信息
在SocialConfig类把ConnectController添加到bean
// 这个是提供查询社交账户信息服务,绑定服务,等 @Bean
public ConnectController connectController(
ConnectionFactoryLocator connectionFactoryLocator,
ConnectionRepository connectionRepository) {
return new ConnectController(connectionFactoryLocator, connectionRepository);
}
ConnectController
org.springframework.social.connect.web.ConnectController
public String connectionStatus(NativeWebRequest request, Model model) { this.setNoCache(request);
this.processFlash(request, model);
Map<String, List<Connection<?>>> connections = this.connectionRepository.findAllConnections();
model.addAttribute("providerIds", this.connectionFactoryLocator.registeredProviderIds());
model.addAttribute("connectionMap", connections);
return this.connectView();
}
在connectionStatus方法打断点,启动项目访问:域名/connect
我当前登录的账号绑定了QQ没有绑定weixin,继续下一步看跳默认转到哪
默认跳转:connect/status 这个页面没有我们重写一下
ConnectionStatusView
com.spring.security.social创建ConnectionStatusView类
package com.spring.security.social;import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.social.connect.Connection;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.view.AbstractView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 读取第三方绑定数据
*/
@Component("connect/status")
public class ConnectionStatusView extends AbstractView {
@Autowired
private ObjectMapper objectMapper;
@Override
protected void renderMergedOutputModel(Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception {
//取model里封装好的信息
Map<String, List<Connection<?>>> connections = (Map<String, List<Connection<?>>>) model.get("connectionMap");
//返回报文 是否绑定
Map<String, Boolean> r = new HashMap<>();
//遍历connections里面数据
for (String key : connections.keySet()) {
//判断取出来的值是否为null 返回是否
r.put(key, CollectionUtils.isNotEmpty(connections.get(key)));
}
response.setContentType("application/json;charset=UTF-8");
response.getWriter().write(objectMapper.writeValueAsString(r));
}
}
重启项目看是否能返回报文:
绑定
绑定源码,重新走认证流程
/** * Process a connect form submission by commencing the process of establishing a connection to the provider on behalf of the member.
* For OAuth1, fetches a new request token from the provider, temporarily stores it in the session, then redirects the member to the provider"s site for authorization.
* For OAuth2, redirects the user to the provider"s site for authorization.
* @param providerId the provider ID to connect to
* @param request the request
* @return a RedirectView to the provider"s authorization page or to the connection status page if there is an error
*/
@RequestMapping(value="/{providerId}", method=RequestMethod.POST)
public RedirectView connect(@PathVariable String providerId, NativeWebRequest request) {
ConnectionFactory<?> connectionFactory = connectionFactoryLocator.getConnectionFactory(providerId);
MultiValueMap<String, String> parameters = new LinkedMultiValueMap<String, String>();
preConnect(connectionFactory, parameters, request);
try {
return new RedirectView(connectSupport.buildOAuthUrl(connectionFactory, request, parameters));
} catch (Exception e) {
sessionStrategy.setAttribute(request, PROVIDER_ERROR_ATTRIBUTE, e);
return connectionStatusRedirect(providerId, request);
}
}
创建banding.html页面
<!DOCTYPE html><html lang="en">
<head>
<meta charset="UTF-8">
<title>标准绑定页面</title>
</head>
<body>
<h2>标准绑定解绑页面</h2>
<form action="/connect/qq" method="post">
<button type="submit">绑定QQ</button>
</form>
<form action="/connect/weixin" method="post">
<button type="submit">绑定微信</button>
</form>
</body>
</html>
启动项目测试
使用表单登录访问页面banding.html
清空数据库表:
点击绑定QQ
如果出现这个错误请把/connect/qq加到QQ互联的回调地址:http://127.0.0.1/auth/qq;http://127.0.0.1/connect/qq
继续登录:
数据已经绑定成功,但是绑定成功以后的跳转报错,现在做一下绑定成功以后的跳转
绑定成功跳转
com.spring.security.social目录创建HkConnectView绑定成功和解绑成功跳转视图类
package com.spring.security.social;import org.springframework.web.servlet.view.AbstractView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;
/**
* 绑定成功和解绑成功跳转视图 需要放配置中管理bean
*/
public class HkConnectView extends AbstractView {
@Override
protected void renderMergedOutputModel(Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception {
response.setContentType("text/html;charset=UTF-8");
if (model.get("connections") == null) {
response.getWriter().write("<h3>" + model.get("providerId") + "解绑成功</h3>");
} else {
response.getWriter().write("<h3>" + model.get("providerId") + "绑定成功</h3>");
}
}
}
注入绑定bean
QQAutoConfig类添加bean配置
/** * QQ绑定解绑界面视图
* connect/qqConnected:绑定
* connect/qqConnect:解绑
*
* @return
*/
@Bean({"connect/qqConnect", "connect/qqConnected"})
@ConditionalOnMissingBean(name = "qqConnectedView") //可以自定义实现覆盖此默认界面
public HkConnectView qqConnectedView() {
return new HkConnectView();
}
WeixinAutoConfig类添加bean配置
/** * weixin绑定解绑界面视图
* connect/weixinConnected:绑定
* connect/weixinConnect:解绑
*
* @return
*/
@Bean({"connect/weixinConnect", "connect/weixinConnected"})
@ConditionalOnMissingBean(name = "weixinConnectedView") //可以自定义实现覆盖此默认界面
public HkConnectView weixinConnectedView() {
return new HkConnectView();
}
启动项目测试,清空数据库表:
绑定就到此结束了。
解绑
解绑源码
/** * Remove all provider connections for a user account.
* The user has decided they no longer wish to use the service provider from this application.
* Note: requires {@link HiddenHttpMethodFilter} to be registered with the "_method" request parameter set to "DELETE" to convert web browser POSTs to DELETE requests.
* @param providerId the provider ID to remove the connections for
* @param request the request
* @return a RedirectView to the connection status page
*/
@RequestMapping(value="/{providerId}", method=RequestMethod.DELETE)
public RedirectView removeConnections(@PathVariable String providerId, NativeWebRequest request) {
ConnectionFactory<?> connectionFactory = connectionFactoryLocator.getConnectionFactory(providerId);
preDisconnect(connectionFactory, request);
connectionRepository.removeConnections(providerId);
postDisconnect(connectionFactory, request);
return connectionStatusRedirect(providerId, request);
}
解绑和绑定请求地址是一样的,区别:
- 绑定是POST请求
- 解绑是DELETE请求
DELETE无法用表单发送请求只能用postman模拟实现
以上是 【SpringSecurity+OAuth2+JWT入门到实战】16.第三方登录绑定和解绑 的全部内容, 来源链接: utcz.com/z/514368.html