1. OAuth2簡易實戰(四)-Github社交聯合登錄  1.1. 用到的第三方插件  https://github.com/spring-projects/spring-social-github 
1.2. 測試步驟  1.2.1. 先在github上注冊一個OAuth Apps  
 需要注意的,這里的最后一個回調地址的配置,格式嚴格規定,/connect/xxx,最后的github參數對應了特定頁面,后面我通過閱讀源碼來詳細解釋 注冊完之后,會有一個client id和client secret,這是需要配置到程序中的 1.2.2. 屬性配置  applicaton.properties spring.social.github.app-id=xxxx
spring.social.github.app-secret=xxxx 
屬性類 @ConfigurationProperties(prefix = "spring.social.github")
public class GitHubProperties extends SocialProperties {} 
1.2.3. social核心配置  屬性配置導入,建立與github連接 @Configuration
@EnableSocial
@EnableConfigurationProperties(GitHubProperties.class)
public class GitHubConfiguration extends SocialAutoConfigurerAdapter {private final GitHubProperties properties;public GitHubConfiguration(GitHubProperties properties) {this.properties = properties;}@Bean@Scope(value = "request", proxyMode = ScopedProxyMode.INTERFACES)public GitHub gitHub(ConnectionRepository repository) {Connection<GitHub> connection = repository.findPrimaryConnection(GitHub.class);return connection != null ? connection.getApi() : null;}@Beanpublic ConnectController connectController(ConnectionFactoryLocator factoryLocator,ConnectionRepository repository) {ConnectController controller = new ConnectController(factoryLocator, repository);controller.setApplicationUrl("http://localhost:8080");return controller;}@Overrideprotected ConnectionFactory<?> createConnectionFactory() {return new GitHubConnectionFactory(properties.getAppId(),properties.getAppSecret());}
} 
1.2.4. controller層  @Controller
public class RepositoriesController {@Autowiredprivate GitHub github;@Autowiredprivate ConnectionRepository connectionRepository;@GetMappingpublic String repositories(Model model) {if (connectionRepository.findPrimaryConnection(GitHub.class) == null) {return "redirect:/connect/github";}String name = github.userOperations().getUserProfile().getUsername();String username = github.userOperations().getUserProfile().getUsername();model.addAttribute("name", name);String uri = "https://api.github.com/users/{user}/repos";GitHubRepo[] repos = github.restOperations().getForObject(uri,GitHubRepo[].class, username);model.addAttribute("repositories", Arrays.asList(repos));return "repositories";}} 
當我們請求localhost:8080 會重定向到localhost:8080/connect/github ,這又是寫在哪呢?查看源代碼,會發現在social-web包的ConnectController類中有 @Controller
@RequestMapping({"/connect"})
public class ConnectController implements InitializingBean {     @RequestMapping(value = {"/{providerId}"},method = {RequestMethod.GET})public String connectionStatus(@PathVariable String providerId, NativeWebRequest request, Model model) {this.setNoCache(request);this.processFlash(request, model);List<Connection<?>> connections = this.connectionRepository.findConnections(providerId);this.setNoCache(request);if (connections.isEmpty()) {return this.connectView(providerId);} else {model.addAttribute("connections", connections);return this.connectedView(providerId);}} 
進入connectView方法     protected String connectView(String providerId) {return this.getViewPath() + providerId + "Connect";} 
可以看到,在這里它固定拼接了參數Connect,所以,在自己的跳轉頁面中需要有特定的命名規范,這里一定就是githubConnect.html了 <html>
<head><title>Social Authcode</title>
</head>
<body><h2>Connect to GitHub to see your repositories</h2><form action="/connect/github" method="POST"><input type="hidden" name="scope" value="public_repo user" /><div class="formInfo">Click the button to share your repositories with <b>social-github</b></div><p><button type="submit">Connect to GitHub</button></p></form></body>
</html> 
顯示頁面如下 
 點擊按鈕進行post請求,進入源碼如下     @RequestMapping(value = {"/{providerId}"},method = {RequestMethod.POST})public RedirectView connect(@PathVariable String providerId, NativeWebRequest request) {ConnectionFactory<?> connectionFactory = this.connectionFactoryLocator.getConnectionFactory(providerId);MultiValueMap<String, String> parameters = new LinkedMultiValueMap();this.preConnect(connectionFactory, parameters, request);try {return new RedirectView(this.connectSupport.buildOAuthUrl(connectionFactory, request, parameters));} catch (Exception var6) {this.sessionStrategy.setAttribute(request, "social_provider_error", var6);return this.connectionStatusRedirect(providerId, request);}} 
層層深入后,會發現它本質還是在組裝授權參數,使用的是OAuth2的授權碼模式,最后組裝的http請求為如下,很明顯為了去獲得授權碼 https://github.com/login/oauth/authorize?client_id=9fc0081c3dd4f8b11f86&response_type=code&redirect_uri=http%3A%2F%2Flocalhost%3A8080%2Fconnect%2Fgithub&scope=public_repo+user&state=e37f1891-cd45-47b4-adb4-5c541f777e60&state=48742b99-c04e-4dfd-af0a-f19b0193f1bb&state=c2737022-3cc7-4b80-92ce-fcba2ca9beb4 
這最后跳轉這層的代碼如下,封裝成buildOAuthUrl方法進行了組裝     public RedirectView connect(@PathVariable String providerId, NativeWebRequest request) {ConnectionFactory<?> connectionFactory = this.connectionFactoryLocator.getConnectionFactory(providerId);MultiValueMap<String, String> parameters = new LinkedMultiValueMap();this.preConnect(connectionFactory, parameters, request);try {return new RedirectView(this.connectSupport.buildOAuthUrl(connectionFactory, request, parameters));} catch (Exception var6) {this.sessionStrategy.setAttribute(request, "social_provider_error", var6);return this.connectionStatusRedirect(providerId, request);}} 
獲取授權碼后,跳轉github登錄頁面
輸入用戶名密碼正確后立即回調到方法
    @RequestMapping(value = {"/{providerId}"},method = {RequestMethod.GET},params = {"code"})public RedirectView oauth2Callback(@PathVariable String providerId, NativeWebRequest request) {try {OAuth2ConnectionFactory<?> connectionFactory = (OAuth2ConnectionFactory)this.connectionFactoryLocator.getConnectionFactory(providerId);Connection<?> connection = this.connectSupport.completeConnection(connectionFactory, request);this.addConnection(connection, connectionFactory, request);} catch (Exception var5) {this.sessionStrategy.setAttribute(request, "social_provider_error", var5);logger.warn("Exception while handling OAuth2 callback (" + var5.getMessage() + "). Redirecting to " + providerId + " connection status page.");}return this.connectionStatusRedirect(providerId, request);} 
通過授權碼再去取得token 
 再繼續跳轉/connect/github  @RequestMapping(value = {"/{providerId}"},method = {RequestMethod.GET})public String connectionStatus(@PathVariable String providerId, NativeWebRequest request, Model model) {this.setNoCache(request);this.processFlash(request, model);List<Connection<?>> connections = this.connectionRepository.findConnections(providerId);this.setNoCache(request);if (connections.isEmpty()) {return this.connectView(providerId);} else {model.addAttribute("connections", connections);return this.connectedView(providerId);}} 
此時connections有值,進入connectedView方法     protected String connectedView(String providerId) {return this.getViewPath() + providerId + "Connected";} 
由此可以知道,下個頁面我們命名也定下來了,githubConnected.html,這里簡單一個點擊連接,跳轉到主頁 <html><head><title>Social Authcode</title></head><body><h2>Connected to GitHub</h2><p>Click <a href="/">here</a> to see your repositories.</p></body>
</html> 
 到此其實授權操作都已經完成了,接下來就是正式調用github需要權限的接口了,點擊here 
  代碼學習地址 https://github.com/spring2go/oauth2lab
  
 
轉載于:https://www.cnblogs.com/sky-chen/p/10530678.html
                            總結 
                            
                                以上是生活随笔 為你收集整理的OAuth2简易实战(四)-Github社交联合登录 的全部內容,希望文章能夠幫你解決所遇到的問題。
                            
                            
                                如果覺得生活随笔 網站內容還不錯,歡迎將生活随笔 推薦給好友。