facebook第三方登录三种实现方式:第三种我认为方便简单
1.js sdk 直接在官网看文档 直接调用他的sdk 官网:https://developers.facebook.com/docs/facebook-login/web
2.自己抒写在服务端验证方式第三方登录:
2.1首先登录facebook 注册自己应用
2.2然后配置一些回调地址
![](https://img-blog.csdnimg.cn/288db25e5ce64765b7870298951afc6e.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6Ieq5L-h77yM6KOF6L295piO5aSp,size_20,color_FFFFFF,t_70,g_se,x_16)
回调地址自己可以内网穿透实现一下
2.3其次就是 如下图的 应用编号,和应用密钥一会需要
3.然后就是后端代码
3.1第一步 重定向跳转授权地址(这个授权地址可以返回给前端,前端控制跳转。前端控制的好处就是,可以将第三方的授权页嵌入到iframe中,适配网站设计)
3.2写回调接口(就是上边图片)有效OAuth 跳转url(代码中有细致的获取用户信息步骤)
3.3判断扫码成功
下面看代码
package art.quanse.pixabay.service; import java.io.IOException; import java.util.Date; import java.util.HashMap; import java.util.Optional; import java.util.UUID; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import com.alibaba.fastjson.JSONObject; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import art.quanse.common.Hs; import art.quanse.pixabay.entity.PixabayUser; import art.quanse.pixabay.entity.SpringUserToken; import art.quanse.pixabay.repository.PixabayUserRepository; import art.quanse.pixabay.repository.SpringUserTokenRepository; import art.quanse.pixabay.util.HttpHelper; @RestController public class RestAuthController { @Autowired SpringUserTokenRepository springUserTokenRepository; @Autowired private PixabayUserRepository pixabayUserRepository; private ObjectMapper objMapper = new ObjectMapper(); protected Logger logger = LogManager.getLogger(this); // 应用编号 private static String client_id = "3004389089872349"; // 应用秘钥 private static String client_secret = "692a53db3ac80e8d5c3574707e6b9947"; // 回调地址 private static String redirect_url = "https://chen2580.mynatapp.cc/pixabay_api/api/facebookLogin/login"; // 获取tokenUrl private static String token_url = "https://graph.facebook.com/v12.0/oauth/access_token"; // 获取用户信息 private static String user_url = "https://graph.facebook.com/me"; // 获取临时口令(code) private static String code_url = "https://www.facebook.com/v12.0/dialog/oauth?"; //判断是否扫码登录成功 private boolean isLogin=false; /** * * 第一步 重定向到授权地址 * * @param request * @param response * @throws IOException */ @RequestMapping(value = "/code") public static void getAuthorizationCode(HttpServletRequest request, HttpServletResponse response) throws IOException { response.sendRedirect( code_url + "client_id=" + client_id + "&redirect_uri=" + redirect_url); } /** * 第二步回调接口 * * @param request * @param response * @return * @throws IOException */ @RequestMapping("/callback") public Hs<JSONObject> verify(HttpServletRequest request, HttpServletResponse response) throws IOException { String code = request.getParameter("code"); String access_token = request.getParameter("access_token"); try { logger.info("获取到的code:{}", code); logger.info("获取到的access_token:{}", access_token); String facebookAccessToken = this.getFacebookAccessToken(code);// 1.根据code获取 AccessToken boolean verify = this.verify(facebookAccessToken);// 2.判断是否是自己应用授权用户信息 JSONObject userInfo = this.getUserInfo(facebookAccessToken);//3 根据access_token获取用户信息 if (verify) { isLogin=true; //获取到facebook用户信息自己处理下边是我自己的需求 PixabayUser saveUserMessage = this.saveUserMessage(userInfo); if (null != saveUserMessage) { SpringUserToken generateToken = generateToken(saveUserMessage.getId()); userInfo.put("token", generateToken.getToken()); } } return new Hs<>(userInfo); } catch (Exception e) { logger.info("获取到的code{}", code); } return new Hs<>(9401, "身份验证失败,重新认证"); } /** * 第三步 判断用户是否扫码登录成功 * * @return */ public Hs<Void> isLogin() { if (isLogin) { return new Hs<>(200,"登录成功"); //此处可以返回token 此简单处理了 } return new Hs<>(9401,"登录失败"); } /** * * * 防止别人拿其他平台的appId授权的token来请求 * * @param access_token * @return * @throws IOException */ public boolean verify(String access_token) throws IOException { StringBuilder stringBuilder = new StringBuilder("https://graph.facebook.com/debug_token?access_token="); stringBuilder.append(client_id + "%7C" + client_secret).append("&input_token=").append(access_token); String result = HttpHelper.getJson(stringBuilder.toString(), "127.0.0.1", 7890); JSONObject readValue = objMapper.readValue(result, JSONObject.class); JSONObject jsonObject = readValue.getJSONObject("data"); try { String isValid = jsonObject.getString("is_valid"); if (null != jsonObject && "true".equals(isValid)) { return true; } } catch (Exception e) { logger.info("验证返回的数据为{}", jsonObject); } return false; } /** * 保存用户信息 * * @param userMessageBean * @return */ private PixabayUser saveUserMessage(JSONObject userInfo) { PixabayUser pixabayUser = null; if (userInfo.getLong("status") == 200) { String username = userInfo.getString("name"); String email = userInfo.getString("email"); String headPortrait = userInfo.getJSONObject("picture").getJSONObject("data").getString("url"); pixabayUser = new PixabayUser(); Optional<PixabayUser> pixAbayUserOptional = pixabayUserRepository.findAllByEmailAddress(email); Integer status = 3; if (pixAbayUserOptional.isPresent()) { pixabayUser = pixAbayUserOptional.get(); status = pixabayUser.getStatus() != 3 ? pixabayUser.getStatus() : 3; } pixabayUser.setEmailAddress(email); pixabayUser.setHeadPortrait(headPortrait); pixabayUser.setUsername(username); pixabayUser.setStatus(status); PixabayUser savePixabayUser = pixabayUserRepository.save(pixabayUser); return savePixabayUser; } return pixabayUser; } /** * 生成用户userId新的登录token * * @param userId * @return */ public SpringUserToken generateToken(long userId) { // 在spring_manager_token表中查找该用户的token Optional<SpringUserToken> oldOpt = this.springUserTokenRepository.findByUserId(userId); SpringUserToken token = new SpringUserToken(); token.setUserId(userId); String tokenString = this.uuidToken(); token.setToken(tokenString); token.setLastDate(new Date()); if (oldOpt.isPresent()) { SpringUserToken old = oldOpt.get(); token.setId(old.getId()); } SpringUserToken saved = this.springUserTokenRepository.save(token); return saved; } /** * 给予UUID生成token,不含“-” * * @return String */ private String uuidToken() { String uuid = UUID.randomUUID().toString(); return uuid.replace("-", ""); } /** * 根据accessToken获取用户信息 * * @param accessToken * @return * @throws JsonProcessingException */ private JSONObject getUserInfo(String accessToken) throws JsonProcessingException { String responseResult = null; JSONObject userInfo = new JSONObject(); if (null != accessToken) { HashMap<String, String> params = new HashMap<String, String>(); String fields = "id,name,birthday,gender,hometown,email,picture"; params.put("access_token", accessToken); params.put("fields", fields); String body = objMapper.writeValueAsString(params); logger.info("请求体{}:", body); try { responseResult = HttpHelper.post(user_url, body, "127.0.0.1", 7890);//设置代理端口请求facebook接口获取用户信息 } catch (Exception e) { e.printStackTrace(); } if (null != responseResult) { String result = responseResult; userInfo = JSONObject.parseObject(result); userInfo.put("status", 200); return userInfo; } } userInfo.put("status", 9404); userInfo.put("message", "请重新认证"); return userInfo; } /** * 根据code获取access_token * * @param code * @return */ public String getFacebookAccessToken(String code) { HashMap<String, String> params = new HashMap<String, String>(); params.put("client_id", client_id); params.put("redirect_uri", redirect_url); params.put("client_secret", client_secret); params.put("code", code); String responseResult = null; String accessToken = null; try { responseResult = HttpHelper.post(token_url, objMapper.writeValueAsString(params), "127.0.0.1", 7890); } catch (Exception e) { e.printStackTrace(); } if (null != responseResult) { String result = responseResult; JSONObject jsonObject = JSONObject.parseObject(result); accessToken = jsonObject.getString("access_token"); } return accessToken; } public void getCode(HttpServletRequest request, HttpServletResponse response) throws IOException { String code_url = "https://www.facebook.com/v13.0/dialog/oauth"; response.sendRedirect(code_url + "?client_id=" + client_id + "&redirect_uri=" + redirect_url); } }
第三方式通过JustAuth
框架实现,这个框架简单集成好多第三方登录方便简单,默认实现state 三分钟缓存 可以防止csrf。如果自定义缓存实现AuthStateCache接口,可以git看一这个框架 代码思想风格不错对于刚实习的我
引入依赖
<dependency> <groupId>me.zhyd.oauth</groupId> <artifactId>JustAuth</artifactId> <version>1.16.4</version> </dependency>
创建Request
AuthRequest authRequest = new AuthFacebookRequest(AuthConfig.builder()
.clientId("Client ID")
.clientSecret("Client Secret")
.redirectUri("应用回调地址")
// 针对国外平台配置代理
.httpConfig(HttpConfig.builder()
.timeout(15000)
// host 和 port 请修改为开发环境的参数
.proxy(new Proxy(Proxy.Type.HTTP, new InetSocketAddress("127.0.0.1", 10080)))
.build())
.build());
生成授权地址
我们可以直接使用以下方式生成第三方平台的授权链接:
String authorizeUrl = authRequest.authorize(AuthStateUtils.createState());
以上完整代码如下
package art.quanse.demo.controller;
import java.io.IOException;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import art.quanse.demo.component.AuthRequestComponent;
import me.zhyd.oauth.model.AuthCallback;
import me.zhyd.oauth.request.AuthRequest;
import me.zhyd.oauth.utils.AuthStateUtils;
@RestController
@RequestMapping("/oauth")
public class RestAuthController {
@Autowired
AuthRequestComponent authRequestComponent;
/**
* 重定向授权地址
*
* @param response
* @throws IOException
*/
@RequestMapping("/render")
public void renderAuth(HttpServletResponse response) throws IOException {
AuthRequest authRequest = authRequestComponent.getAuthRequest();
response.sendRedirect(authRequest.authorize(AuthStateUtils.createState()));
}
/**
* 回调接口获取用户信息
*
* @param callback
* @return
*/
@RequestMapping("/callback")
public Object login(AuthCallback callback) {
AuthRequest authRequest = authRequestComponent.getAuthRequest();
return authRequest.login(callback);
}
}
欢迎大神给与介意,刚实习公司给的任务
版权归原作者 自信,装载明天 所有, 如有侵权,请联系我们删除。