Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/spring-boot/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Spring boot 如何使用Spring(java)验证facebook授权令牌并注册用户_Spring Boot_Spring Security Oauth2_Spring Oauth2_Spring Security Rest - Fatal编程技术网

Spring boot 如何使用Spring(java)验证facebook授权令牌并注册用户

Spring boot 如何使用Spring(java)验证facebook授权令牌并注册用户,spring-boot,spring-security-oauth2,spring-oauth2,spring-security-rest,Spring Boot,Spring Security Oauth2,Spring Oauth2,Spring Security Rest,我正在开发一个应用程序,其前端使用React.js编写,后端RESTAPI使用Spring框架编写。我想在我的网站上添加社交登录,所以经过几天的谷歌搜索和研究,我知道OAuth2是解决方案。我知道前端应该处理从资源服务器(这里是Facebook)获取授权令牌的问题,后端(java)应该验证该令牌并与Facebook连接以获取访问令牌。然后,访问令牌应与用户详细信息(如电子邮件)一起存储在我的数据库中 这是我的要求,一旦用户单击“继续使用Facebook”按钮,我的应用程序应该使用详细信息-电子邮

我正在开发一个应用程序,其前端使用React.js编写,后端RESTAPI使用Spring框架编写。我想在我的网站上添加社交登录,所以经过几天的谷歌搜索和研究,我知道OAuth2是解决方案。我知道前端应该处理从资源服务器(这里是Facebook)获取授权令牌的问题,后端(java)应该验证该令牌并与Facebook连接以获取访问令牌。然后,访问令牌应与用户详细信息(如电子邮件)一起存储在我的数据库中

这是我的要求,一旦用户单击“继续使用Facebook”按钮,我的应用程序应该使用详细信息-电子邮件和姓名(注册功能)在我自己的数据库中创建帐户。之后,每当他们再次单击此按钮时,他们将登录而不是注册。其他网站处理它的方式

到目前为止,我的应用程序中有一个按钮,它给我带来了来自Facebook的授权令牌

有人能给我指路吗


此外,我还应该特别注意一些错误处理。

以下是使用Spring Boot作为REST API的一般方法,它由Spring Data JPA和Spring Security支持,可同时用于iOS和
ember.js
。可能有一些库以及其他你不能使用的东西,但我只想概述一下基本流程

  • 您的用户对象需要一对一映射到facebook帐户。最佳实践包括在存储到数据库之前对
    authToken
    进行加密
  • 使用获取用户访问令牌和用户的Facebook用户ID。在成功的情况下,您将在react应用程序中从Facebook获得如下响应:
  • 使用步骤2中接收到的信息点击一些登录端点,如
    /login/facebook
    。我无法预测你的应用程序的结构。在我的应用程序中,此代码由实现
    GenericFilterBean
    的身份验证过滤器处理。我用令牌传递一个标题
    X-Auth-Facebook

  • 验证令牌。我在一个类中这样做,该类在
    Authentication Authentication(Authentication Authentication)抛出AuthenticationException
    方法中实现了
    AuthenticationProvider
    。此类将需要应用程序的访问令牌
    accessToken
    和用户令牌
    userAccessToken

  • 一、 就个人而言,然后创建一个令牌,供我的客户在访问我的API时使用(而不是让他们在所有请求中继续传递facebook令牌)

    我还需要更多用户提供的信息来创建用户(选择用户名、同意条款和条件等)。因此,我的实际实现抛出了一个
    EntityNotFoundException
    ,而不是创建用户,然后我的客户端使用该用户弹出一个注册表,该注册表只提供我无法从facebook获得的字段。从客户端提交此消息时,我使用facebook令牌和创建我的用户所需的内容点击我的
    /signup/facebook
    端点。我从facebook获取个人资料并创建用户(在过程中自动记录他们)

    编辑:如果要使用Spring 0Auth,可以按照创建Spring 2 Oauth Rest模板的步骤进行操作

    @Bean
    public OAuth2ProtectedResourceDetails facebook() {
        AuthorizationCodeResourceDetails details = new AuthorizationCodeResourceDetails();
        details.setId("facebook");
        details.setClientId("233668646673605");
        details.setClientSecret("33b17e044ee6a4fa383f46ec6e28ea1d");
        details.setAccessTokenUri("https://graph.facebook.com/oauth/access_token");
        details.setUserAuthorizationUri("https://www.facebook.com/dialog/oauth");
        details.setTokenName("oauth_token");
        details.setAuthenticationScheme(AuthenticationScheme.query);
        details.setClientAuthenticationScheme(AuthenticationScheme.form);
        return details;
    }
    
    @Bean
    public OAuth2RestTemplate facebookRestTemplate(OAuth2ClientContext clientContext) {
        OAuth2RestTemplate template = new OAuth2RestTemplate(facebook(), clientContext);
        MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
        converter.setSupportedMediaTypes(Arrays.asList(MediaType.APPLICATION_JSON,
                MediaType.valueOf("text/javascript")));
        template.setMessageConverters(Arrays.<HttpMessageConverter<?>> asList(converter));
        return template;
    }
    
    @Bean
    公共OAuth2ProtectedResourceDetails facebook(){
    AuthorizationCodeResourceDetails=新的AuthorizationCodeResourceDetails();
    详情。setId(“facebook”);
    详情。setClientId(“233668646673605”);
    详细信息。setClientSecret(“33b17e044ee6a4fa383f46ec6e28ea1d”);
    详细信息。setAccessTokenUri(“https://graph.facebook.com/oauth/access_token");
    详细信息。setUserAuthorizationUri(“https://www.facebook.com/dialog/oauth");
    详细信息:setTokenName(“oauth_令牌”);
    details.setAuthenticationScheme(AuthenticationScheme.query);
    setClientAuthenticationScheme(AuthenticationScheme.form);
    退货详情;
    }
    @豆子
    公共OAuth2RestTemplate facebookRestTemplate(OAuth2ClientContext客户端上下文){
    OAuth2RestTemplate=新的OAuth2RestTemplate(facebook(),clientContext);
    MappingJackson2HttpMessageConverter=新的MappingJackson2HttpMessageConverter();
    converter.setSupportedMediaTypes(Arrays.asList(MediaType.APPLICATION_JSON,
    MediaType.valueOf(“text/javascript”);
    
    template.setMessageConverters(Arrays.Spring有一个Facebook auth项目,该项目使用Spring Security integration@WildDev。我的发现对吗?当我从前端获取授权令牌时,这是正确的方法吗?还是应该在后端执行所有操作?在后端执行所有操作都会在重定向中产生问题,因为这是一个REST api。这与后端配置有关n、 «继续使用Facebook»默认为本机表单提交者按钮。提交目标为Spring Security endpoint,通过绕过前端逻辑的外部重定向到社交网络进行响应。完成身份验证后,用户将重定向回预定义的返回url。从这一点开始,
    身份验证
    对象包含用户数据,如社交ID等。@ WaldDeV考虑此场景-用户点击“继续使用脸谱网”按钮,按钮与后端API端点<代码> / AUTH/脸谱网> /代码>。Spring Security与脸谱网连接,然后1。如果用户未登录,则脸谱网重定向到登录页面2。这是第一次,用户需要授予对我的应用程序的访问权限,这也需要重定向到fb URL。我的困惑是,REST API如何处理此重定向。例如,在浏览器上(前端)这很简单。我不确定
    /auth/facebook
    端点是否支持
    REST
    体系结构所需的异步请求。文档中最常见的一种是使用同步请求和以下浏览器重定向。没有要求
    @Entity
    class User{
    
    ...
    @OneToOne(mappedBy = "user", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
        FacebookAccount facebookAccount
    }
    
    {
        status: 'connected',
        authResponse: {
            accessToken: '...',
            expiresIn:'...',
            reauthorize_required_in:'...'
            signedRequest:'...',
            userID:'...'
        }
    }
    
    URIBuilder builder = URIBuilder.fromUri(String.format("%s/debug_token", "https://graph.facebook.com"))
    builder.queryParam("access_token", accessToken)
    builder.queryParam("input_token", userAccessToken)
    URI uri = builder.build()
    RestTemplate restTemplate = new RestTemplate()
    
    JsonNode resp = null
    try {
        resp = restTemplate.getForObject(uri, JsonNode.class)
    } catch (HttpClientErrorException e) {
        throw new AuthenticationServiceException("Error requesting facebook debug_token", e)
    }
    
    Boolean isValid = resp.path("data").findValue("is_valid").asBoolean()
    if (!isValid)
        throw new BadCredentialsException("Token not valid")
    
    String fbookUserId = resp.path("data").findValue("user_id").textValue()
    if (!fbookUserId)
        throw new AuthenticationServiceException("Unable to read user_id from facebook debug_token response")
    
    // spring data repository that finds the FacebookAccount by facebook user id
    FacebookAccount fbookAcct = facebookAccountRepository.findByFacebookUserId(fbookUserId)
    if(!fbookAcct){
        // create your user here
        // save the facebook account as well
    } else{
      // update the existing users token
      fbookAcct.authToken = userAccessToken
      facebookAccountRepository.save(fbookAcct)
    }
    // finish the necessary steps in creating a valid Authentication
    
    
    @Bean
    public OAuth2ProtectedResourceDetails facebook() {
        AuthorizationCodeResourceDetails details = new AuthorizationCodeResourceDetails();
        details.setId("facebook");
        details.setClientId("233668646673605");
        details.setClientSecret("33b17e044ee6a4fa383f46ec6e28ea1d");
        details.setAccessTokenUri("https://graph.facebook.com/oauth/access_token");
        details.setUserAuthorizationUri("https://www.facebook.com/dialog/oauth");
        details.setTokenName("oauth_token");
        details.setAuthenticationScheme(AuthenticationScheme.query);
        details.setClientAuthenticationScheme(AuthenticationScheme.form);
        return details;
    }
    
    @Bean
    public OAuth2RestTemplate facebookRestTemplate(OAuth2ClientContext clientContext) {
        OAuth2RestTemplate template = new OAuth2RestTemplate(facebook(), clientContext);
        MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
        converter.setSupportedMediaTypes(Arrays.asList(MediaType.APPLICATION_JSON,
                MediaType.valueOf("text/javascript")));
        template.setMessageConverters(Arrays.<HttpMessageConverter<?>> asList(converter));
        return template;
    }
    
    public String photos(Model model) throws Exception {
            ObjectNode result = facebookRestTemplate
                    .getForObject("https://graph.facebook.com/me/friends", ObjectNode.class);
            ArrayNode data = (ArrayNode) result.get("data");
            ArrayList<String> friends = new ArrayList<String>();
            for (JsonNode dataNode : data) {
                friends.add(dataNode.get("name").asText());
            }
            model.addAttribute("friends", friends);
            return "facebook";
        }