You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
136 lines
5.6 KiB
136 lines
5.6 KiB
package com.kob.backend.service.impl.user.account.acwing; |
|
|
|
import com.alibaba.fastjson.JSON; |
|
import com.alibaba.fastjson.JSONObject; |
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; |
|
import com.kob.backend.mapper.UserMapper; |
|
import com.kob.backend.pojo.User; |
|
import com.kob.backend.service.impl.user.account.acwing.utils.HttpClientUtil; |
|
import com.kob.backend.service.user.account.acwing.AcappService; |
|
import com.kob.backend.utils.JwtUtil; |
|
import org.apache.http.NameValuePair; |
|
import org.apache.http.message.BasicNameValuePair; |
|
import org.springframework.beans.factory.annotation.Autowired; |
|
import org.springframework.data.redis.core.RedisTemplate; |
|
import org.springframework.stereotype.Service; |
|
|
|
import java.io.UnsupportedEncodingException; |
|
import java.net.URLEncoder; |
|
import java.time.Duration; |
|
import java.util.ArrayList; |
|
import java.util.LinkedList; |
|
import java.util.List; |
|
import java.util.Random; |
|
|
|
@Service |
|
public class AcappServiceImpl implements AcappService { |
|
private static final String appId = "3357"; |
|
private static final String appSecret = "f343ff7eeaa649d2a257bffac0a9323a"; |
|
private static final String redirectUri = "https://kob.bnblogs.cc/api/user/account/acwing/acapp/receive_code/"; |
|
private static final String applyAccessTokenUrl = "https://www.acwing.com/third_party/api/oauth2/access_token/"; |
|
private static final String getUserInfoUrl = "https://www.acwing.com/third_party/api/meta/identity/getinfo/"; |
|
private static final Random random = new Random(); |
|
|
|
@Autowired |
|
private UserMapper userMapper; |
|
|
|
@Autowired |
|
private RedisTemplate<String,String> redisTemplate; |
|
@Override |
|
public JSONObject applyCode() { |
|
JSONObject resp = new JSONObject(); |
|
resp.put("appid",appId); |
|
try { |
|
resp.put("redirect_uri", URLEncoder.encode(redirectUri,"UTF-8")); |
|
} catch (UnsupportedEncodingException e) { |
|
e.printStackTrace(); |
|
resp.put("result","failed"); |
|
return resp; |
|
} |
|
|
|
resp.put("scope","userinfo"); |
|
|
|
StringBuilder state = new StringBuilder(); |
|
for (int i = 0; i < 10; i++) { |
|
state.append((char)(random.nextInt(10) + '0')); // 十位随机数字字符串 |
|
} |
|
resp.put("state",state.toString()); |
|
resp.put("result","success"); |
|
redisTemplate.opsForValue().set(state.toString(),"true"); // 将state值存入redis |
|
redisTemplate.expire(state.toString(), Duration.ofMinutes(10)); // 设置过期时间为10分钟 |
|
return resp; |
|
} |
|
|
|
@Override |
|
public JSONObject receiveCode(String code, String state) { |
|
JSONObject resp = new JSONObject(); |
|
resp.put("result","failed"); |
|
if (code == null || state == null) return resp; // 传入的code和state为空 |
|
if (Boolean.FALSE.equals(redisTemplate.hasKey(state))) return resp; // redis中没有该state |
|
redisTemplate.delete(state); // 删除该state,只使用一次 |
|
|
|
// 获取accessToken |
|
List<NameValuePair> nameValuePairs = new LinkedList<>(); |
|
nameValuePairs.add(new BasicNameValuePair("appid",appId)); |
|
nameValuePairs.add(new BasicNameValuePair("secret",appSecret)); |
|
nameValuePairs.add(new BasicNameValuePair("code",code)); |
|
|
|
String getString = HttpClientUtil.get(applyAccessTokenUrl,nameValuePairs); // 请求结果存入一个字符串 |
|
|
|
if (getString == null) return resp; |
|
|
|
JSONObject getResp = JSONObject.parseObject(getString); |
|
String accessToken = getResp.getString("access_token"); |
|
String openId = getResp.getString("openid"); |
|
|
|
if (accessToken == null || openId == null) return resp; |
|
|
|
QueryWrapper<User> qw = new QueryWrapper<>(); |
|
qw.eq("openid",openId); |
|
List<User> users = userMapper.selectList(qw); // 查询满足openid的用户是否存在 |
|
if (!users.isEmpty()) { |
|
User user = users.get(0); |
|
String jwt = JwtUtil.createJWT(user.getId().toString()); |
|
resp.put("result","success"); |
|
resp.put("jwt_token",jwt); |
|
return resp; |
|
} |
|
|
|
// 如果不存在说明该用户没有登录过,需要根据上面的accessToken和openid向Acwing请求用户信息 |
|
|
|
nameValuePairs = new LinkedList<>(); |
|
nameValuePairs.add(new BasicNameValuePair("access_token",accessToken)); |
|
nameValuePairs.add(new BasicNameValuePair("openid",openId)); |
|
|
|
getString = HttpClientUtil.get(getUserInfoUrl,nameValuePairs); // 将请求结果存入字符串 |
|
|
|
if (getString == null) return resp; |
|
getResp = JSONObject.parseObject(getString); |
|
// 获得用户的用户名和头像 |
|
String username = getResp.getString("username"); |
|
String photo = getResp.getString("photo"); |
|
|
|
if (username == null || photo == null) return resp; |
|
|
|
// 避免新出现的用户重名 |
|
for (int i = 0; i < 100; i++) { // 随机在后面添加以为数字 |
|
QueryWrapper<User> queryWrapper = new QueryWrapper<>(); |
|
queryWrapper.eq("username",username); |
|
// 没有重名,直接退出 |
|
if (userMapper.selectList(queryWrapper).isEmpty()) break; |
|
username += (char)(random.nextInt(10) + '0'); |
|
if (i == 99) return resp; // 小概率事件,太逆天,直接返回 |
|
} |
|
|
|
// 根据获得的信息建立一个用户 |
|
User user = new User(null,username,null,photo,null,openId); |
|
userMapper.insert(user); |
|
|
|
String jwt = JwtUtil.createJWT(user.getId().toString()); |
|
|
|
resp.put("result","success"); |
|
resp.put("jwt_token",jwt); |
|
|
|
return resp; |
|
} |
|
}
|
|
|