【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

回到顶部