Oauth2.0协议的具体实现细节是怎样的?

2026-05-05 23:531阅读0评论SEO基础
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计1214个文字,预计阅读时间需要5分钟。

Oauth2.0协议的具体实现细节是怎样的?

OAuth(开放授权)是一个开放标准,允许用户授权第三方应用访问他们存储在其他服务提供者上的信息,而无需将用户名和密码提供给第三方应用。这种方式无需泄露用户名和密码,提高了安全性。

  • OAuth: : OAuth(开放授权)是一个开放标准,允许用户授权第三方网站访问他们存储在另外的服务提供者上的信息,而不需要将用户名和密码提供给第三方网站或分享他们数据的所有内容。
  • OAuth2.0 :对于用户相关的 OpenAPI(例如获取用户信息,动态同步,照片,日志,分享等),为了保护用户数据的安全和隐私,第三方网站访问用户数据前都需要显式的向用户征求授权。

一、接入步骤

以微博为例:

  1. 引导用户到微博的认证地址:api.weibo.com/oauth2/authorize?client_id=YOUR_CLIENT_ID&response_type=code&redirect_uri=YOUR_REGISTERED_REDIRECT_URI
  • client_id:微博网站接入提供的 APP KEY;
  • redirect_uri:认证后重定向的地址;
  1. 用户同意授权重定向到上面设置的地址并携带 code:www.gulimall.com/success?code=CODE
  2. 使用 code 请求微博提供的地址换取 access_token:api.weibo.com/oauth2/access_token?client_id=YOUR_CLIENT_ID&client_secret=YOUR_CLIENT_SECRET&grant_type=authorization_code&redirect_uri=YOUR_REGISTERED_REDIRECT_URI&code=CODE
  • client_id:APP KEY;
  • client_secret:APP SECRET;
  • redirect_uri:认证后重定向的地址 www.gulimall.com/success
  • code:第二步返回的 code 值;
  • 返回响应报文:

{ "access_token": "2.00pDpxyGd3J5bEef6b98778e0ZKsu4", "remind_in": "157679999", "expires_in": 157679999, "uid": "6397634785", "isRealName": "true" }

  1. 根据 access_token 可以获取微博提供的公共接口数据;

Oauth2.0协议的具体实现细节是怎样的?

@Override public MemberEntity login(MemberUserLoginVo vo) { String loginacct = vo.getLoginacct(); String password = vo.getPassword(); //1、去数据库查询 SELECT * FROM ums_member WHERE username = ? OR mobile = ? MemberEntity memberEntity = this.baseMapper.selectOne(new QueryWrapper<MemberEntity>() .eq("username", loginacct).or().eq("mobile", loginacct)); if (memberEntity == null) { //登录失败 return null; } else { //获取到数据库里的password String password1 = memberEntity.getPassword(); BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); //进行密码匹配 boolean matches = passwordEncoder.matches(password, password1); if (matches) { //登录成功 return memberEntity; } } return null; } @Override public MemberEntity login(SocialUser socialUser) throws Exception { //具有登录和注册逻辑 String uid = socialUser.getUid(); //1、判断当前社交用户是否已经登录过系统 MemberEntity memberEntity = baseMapper.selectOne(new QueryWrapper<MemberEntity>().eq("social_uid", uid)); if (memberEntity != null) { //这个用户已经注册过 //更新用户的访问令牌的时间和access_token MemberEntity update = new MemberEntity(); update.setId(memberEntity.getId()); update.setAccessToken(socialUser.getAccess_token()); update.setExpiresIn(socialUser.getExpires_in()); baseMapper.updateById(update); memberEntity.setAccessToken(socialUser.getAccess_token()); memberEntity.setExpiresIn(socialUser.getExpires_in()); return memberEntity; } else { //2、没有查到当前社交用户对应的记录我们就需要注册一个 MemberEntity register = new MemberEntity(); //3、查询当前社交用户的社交账号信息(昵称、性别等) Map<String, String> query = new HashMap<>(); query.put("access_token", socialUser.getAccess_token()); query.put("uid", socialUser.getUid()); HttpResponse response = HttpUtils.doGet("api.weibo.com", "/2/users/show.json", "get", new HashMap<>(), query); if (response.getStatusLine().getStatusCode() == 200) { //查询成功 String json = EntityUtils.toString(response.getEntity()); JSONObject jsonObject = JSON.parseObject(json); String name = jsonObject.getString("name"); String gender = jsonObject.getString("gender"); String profileImageUrl = jsonObject.getString("profile_image_url"); register.setNickname(name); register.setGender("m".equals(gender) ? 1 : 0); register.setHeader(profileImageUrl); register.setCreateTime(new Date()); register.setSocialUid(socialUser.getUid()); register.setAccessToken(socialUser.getAccess_token()); register.setExpiresIn(socialUser.getExpires_in()); //把用户信息插入到数据库中 baseMapper.insert(register); } return register; } } @Override public MemberEntity login(String accessTokenInfo) { //从accessTokenInfo中获取出来两个值 access_token 和 oppenid //把accessTokenInfo字符串转换成map集合,根据map里面中的key取出相对应的value Gson gson = new Gson(); HashMap accessMap = gson.fromJson(accessTokenInfo, HashMap.class); String accessToken = (String) accessMap.get("access_token"); String openid = (String) accessMap.get("openid"); //3、拿到access_token 和 oppenid,再去请求微信提供固定的API,获取到扫码人的信息 //TODO 查询数据库当前用用户是否曾经使用过微信登录 MemberEntity memberEntity = this.baseMapper.selectOne(new QueryWrapper<MemberEntity>().eq("social_uid", openid)); if (memberEntity == null) { System.out.println("新用户注册"); //访问微信的资源服务器,获取用户信息 String baseUserInfoUrl = "api.weixin.qq.com/sns/userinfo" + "?access_token=%s" + "&openid=%s"; String userInfoUrl = String.format(baseUserInfoUrl, accessToken, openid); //发送请求 String resultUserInfo = null; try { resultUserInfo = HttpClientUtils.get(userInfoUrl); System.out.println("resultUserInfo==========" + resultUserInfo); } catch (Exception e) { e.printStackTrace(); } //解析json HashMap userInfoMap = gson.fromJson(resultUserInfo, HashMap.class); String nickName = (String) userInfoMap.get("nickname"); //昵称 Double sex = (Double) userInfoMap.get("sex"); //性别 String headimgurl = (String) userInfoMap.get("headimgurl"); //微信头像 //把扫码人的信息添加到数据库中 memberEntity = new MemberEntity(); memberEntity.setNickname(nickName); memberEntity.setGender(Integer.valueOf(Double.valueOf(sex).intValue())); memberEntity.setHeader(headimgurl); memberEntity.setCreateTime(new Date()); memberEntity.setSocialUid(openid); // register.setExpiresIn(socialUser.getExpires_in()); this.baseMapper.insert(memberEntity); } return memberEntity; }

本文共计1214个文字,预计阅读时间需要5分钟。

Oauth2.0协议的具体实现细节是怎样的?

OAuth(开放授权)是一个开放标准,允许用户授权第三方应用访问他们存储在其他服务提供者上的信息,而无需将用户名和密码提供给第三方应用。这种方式无需泄露用户名和密码,提高了安全性。

  • OAuth: : OAuth(开放授权)是一个开放标准,允许用户授权第三方网站访问他们存储在另外的服务提供者上的信息,而不需要将用户名和密码提供给第三方网站或分享他们数据的所有内容。
  • OAuth2.0 :对于用户相关的 OpenAPI(例如获取用户信息,动态同步,照片,日志,分享等),为了保护用户数据的安全和隐私,第三方网站访问用户数据前都需要显式的向用户征求授权。

一、接入步骤

以微博为例:

  1. 引导用户到微博的认证地址:api.weibo.com/oauth2/authorize?client_id=YOUR_CLIENT_ID&response_type=code&redirect_uri=YOUR_REGISTERED_REDIRECT_URI
  • client_id:微博网站接入提供的 APP KEY;
  • redirect_uri:认证后重定向的地址;
  1. 用户同意授权重定向到上面设置的地址并携带 code:www.gulimall.com/success?code=CODE
  2. 使用 code 请求微博提供的地址换取 access_token:api.weibo.com/oauth2/access_token?client_id=YOUR_CLIENT_ID&client_secret=YOUR_CLIENT_SECRET&grant_type=authorization_code&redirect_uri=YOUR_REGISTERED_REDIRECT_URI&code=CODE
  • client_id:APP KEY;
  • client_secret:APP SECRET;
  • redirect_uri:认证后重定向的地址 www.gulimall.com/success
  • code:第二步返回的 code 值;
  • 返回响应报文:

{ "access_token": "2.00pDpxyGd3J5bEef6b98778e0ZKsu4", "remind_in": "157679999", "expires_in": 157679999, "uid": "6397634785", "isRealName": "true" }

  1. 根据 access_token 可以获取微博提供的公共接口数据;

Oauth2.0协议的具体实现细节是怎样的?

@Override public MemberEntity login(MemberUserLoginVo vo) { String loginacct = vo.getLoginacct(); String password = vo.getPassword(); //1、去数据库查询 SELECT * FROM ums_member WHERE username = ? OR mobile = ? MemberEntity memberEntity = this.baseMapper.selectOne(new QueryWrapper<MemberEntity>() .eq("username", loginacct).or().eq("mobile", loginacct)); if (memberEntity == null) { //登录失败 return null; } else { //获取到数据库里的password String password1 = memberEntity.getPassword(); BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); //进行密码匹配 boolean matches = passwordEncoder.matches(password, password1); if (matches) { //登录成功 return memberEntity; } } return null; } @Override public MemberEntity login(SocialUser socialUser) throws Exception { //具有登录和注册逻辑 String uid = socialUser.getUid(); //1、判断当前社交用户是否已经登录过系统 MemberEntity memberEntity = baseMapper.selectOne(new QueryWrapper<MemberEntity>().eq("social_uid", uid)); if (memberEntity != null) { //这个用户已经注册过 //更新用户的访问令牌的时间和access_token MemberEntity update = new MemberEntity(); update.setId(memberEntity.getId()); update.setAccessToken(socialUser.getAccess_token()); update.setExpiresIn(socialUser.getExpires_in()); baseMapper.updateById(update); memberEntity.setAccessToken(socialUser.getAccess_token()); memberEntity.setExpiresIn(socialUser.getExpires_in()); return memberEntity; } else { //2、没有查到当前社交用户对应的记录我们就需要注册一个 MemberEntity register = new MemberEntity(); //3、查询当前社交用户的社交账号信息(昵称、性别等) Map<String, String> query = new HashMap<>(); query.put("access_token", socialUser.getAccess_token()); query.put("uid", socialUser.getUid()); HttpResponse response = HttpUtils.doGet("api.weibo.com", "/2/users/show.json", "get", new HashMap<>(), query); if (response.getStatusLine().getStatusCode() == 200) { //查询成功 String json = EntityUtils.toString(response.getEntity()); JSONObject jsonObject = JSON.parseObject(json); String name = jsonObject.getString("name"); String gender = jsonObject.getString("gender"); String profileImageUrl = jsonObject.getString("profile_image_url"); register.setNickname(name); register.setGender("m".equals(gender) ? 1 : 0); register.setHeader(profileImageUrl); register.setCreateTime(new Date()); register.setSocialUid(socialUser.getUid()); register.setAccessToken(socialUser.getAccess_token()); register.setExpiresIn(socialUser.getExpires_in()); //把用户信息插入到数据库中 baseMapper.insert(register); } return register; } } @Override public MemberEntity login(String accessTokenInfo) { //从accessTokenInfo中获取出来两个值 access_token 和 oppenid //把accessTokenInfo字符串转换成map集合,根据map里面中的key取出相对应的value Gson gson = new Gson(); HashMap accessMap = gson.fromJson(accessTokenInfo, HashMap.class); String accessToken = (String) accessMap.get("access_token"); String openid = (String) accessMap.get("openid"); //3、拿到access_token 和 oppenid,再去请求微信提供固定的API,获取到扫码人的信息 //TODO 查询数据库当前用用户是否曾经使用过微信登录 MemberEntity memberEntity = this.baseMapper.selectOne(new QueryWrapper<MemberEntity>().eq("social_uid", openid)); if (memberEntity == null) { System.out.println("新用户注册"); //访问微信的资源服务器,获取用户信息 String baseUserInfoUrl = "api.weixin.qq.com/sns/userinfo" + "?access_token=%s" + "&openid=%s"; String userInfoUrl = String.format(baseUserInfoUrl, accessToken, openid); //发送请求 String resultUserInfo = null; try { resultUserInfo = HttpClientUtils.get(userInfoUrl); System.out.println("resultUserInfo==========" + resultUserInfo); } catch (Exception e) { e.printStackTrace(); } //解析json HashMap userInfoMap = gson.fromJson(resultUserInfo, HashMap.class); String nickName = (String) userInfoMap.get("nickname"); //昵称 Double sex = (Double) userInfoMap.get("sex"); //性别 String headimgurl = (String) userInfoMap.get("headimgurl"); //微信头像 //把扫码人的信息添加到数据库中 memberEntity = new MemberEntity(); memberEntity.setNickname(nickName); memberEntity.setGender(Integer.valueOf(Double.valueOf(sex).intValue())); memberEntity.setHeader(headimgurl); memberEntity.setCreateTime(new Date()); memberEntity.setSocialUid(openid); // register.setExpiresIn(socialUser.getExpires_in()); this.baseMapper.insert(memberEntity); } return memberEntity; }