这是使用 Spring Boot 作为由 Spring Data JPA 和 Spring Security 支持的 REST API 的一般方法,适用于 iOS 并ember.js
一起工作。可能有库和你不能使用的东西,但我只是要概述基本流程。
- 您的用户对象需要一对一映射到 Facebook 帐户。最佳实践将涉及加密
authToken
存储在数据库中之前
@Entity
class FacebookAccount {
@Id
@GeneratedValue(strategy= GenerationType.AUTO)
Long id
String facebookUserId
String authToken
@OneToOne
@JoinColumn(name="user_id")
User user
}
@Entity
class User{
...
@OneToOne(mappedBy = "user", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
FacebookAccount facebookAccount
}
- 使用facebook Javascript SDK获取用户访问令牌和用户的 Facebook 用户 ID。在成功的情况下,您会在您的 react 应用程序中收到来自 facebook 的回复,如下所示:
{
status: 'connected',
authResponse: {
accessToken: '...',
expiresIn:'...',
reauthorize_required_in:'...'
signedRequest:'...',
userID:'...'
}
}
使用在步骤 2 中收到的信息点击一些登录端点,例如/login/facebook
. 我无法预测您的应用程序的结构。在我的应用程序中,此代码由实现GenericFilterBean
. 我传递了一个X-Auth-Facebook
带有令牌的标题。
验证令牌。我在一个在方法AuthenticationProvider
内实现的类中执行此Authentication authenticate(Authentication authentication) throws AuthenticationException
操作。此类将需要您的 App 的 Access TokenaccessToken
和用户的 Token userAccessToken
:
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
然后,我个人创建一个令牌,供客户在访问我的 API 时使用(而不是让他们继续通过所有请求传递 facebook 令牌)。
我还需要更多用户提供的信息来创建用户(选择的用户名、同意条款和条件等)。所以我的实际实现抛出了一个EntityNotFoundException
而不是创建用户,然后我的客户使用它来弹出一个注册表单,该表单只提供我无法从 facebook 获取的字段。在从客户端提交此内容时,我/signup/facebook
使用 facebook 令牌和创建用户所需的内容点击了我的端点。我从 facebook 获取个人资料并创建用户(在此过程中自动记录他们)。
编辑:如果您想使用 Spring 0Auth,您可以按照示例创建 Spring 2 Oauth Rest Template
@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";
}
我从项目中接受了上述对朋友的要求。debug_token
定制我展示的上述代码以使用 Spring OAuth 休息模板应该不难。希望这可以帮助 :)