java实现微信注册登录

转载请表明出处 https://blog.csdn.net/Amor_Leo/article/details/106843838 谢谢

java实现微信注册登录


微信用户对应一个小程序都有一个唯一的openid,微信授权登录,微信授权登录的核心就是获取这个openid并判断数据库是否存在

微信开放平台

开发准备

  • 登录微信公众平台后台->基本配置->公众号开发信息:
    1.获取到AppID
    2.AppSecret
    3.设置IP白名单

  • 添加网页授权域名
    公众号设置->功能设置
    本地开发的话没有域名,可以使用内网穿透软件,域名要是 https的
    然后按照微信的流程来绑定授权域名就好了。

获取用户信息,需要openid,然而获取openid的话要通过这个接口先获得一个code

  • 用户同意授权,获取code(授权码)
https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect

yaml

wx:
  appid: xxxxxx
  appsecret: xxxxxxx

业务层


    @Value("${wx.appid}")
    private String appid;

    @Value("${wx.appsecret}")
    private String appSecret;


  public Map<String, Object> wxLogin(WxLoginDto wxLoginDto, HttpServletRequest request) {
        Map<String, Object> retMap = new HashMap<>();
        //获取openid 根据前端传过来的微信授权码
        Map<String, Object> result = code2session(wxLoginDto.getCode());
        if (result.containsKey("openid")) {
            String openid = result.get("openid").toString();
            //判断用户是否关联微信 根据openid是否在数据库,没有则注册(新增用户)  具体的逻辑根据自己的业务需求来写
         .......

            String sessionKey = result.get("session_key").toString();
            String token = "";
            Long expiresTime = null;
            //缓存获取access_token
            if (accessTokenService.exists(openid)) {
                token = accessTokenService.getCache(openid).toString();
            } else {
                //获取access_token 保存到redis
                Map<String, Object> resultMap = accessTokenService.getAccessToken();
                if (resultMap != null) { 
                    token = resultMap.get("token").toString();
                    expiresTime = Long.parseLong(String.valueOf(resultMap.get("expires_time")));
                    accessTokenService.setCache(openid, token, expiresTime);
                }
            }
            retMap.put("flag", true);
            Map<String, Object> map = new HashMap<>();
            map.put("openid", openid);
            map.put("token", token);
            map.put("sessionKey", sessionKey);
            // 还有一些用户信息  根据自己的业务需求返回给前端
            .....
            
            retMap.put("userVo", map);
            retMap.put("flag", true);
            return retMap;
        }
        retMap.put("flag", false);
        return retMap;
    }


  public Map<String, Object> code2session(String code) {
        String params = "appid=" + appid + "&secret=" + appSecret + "&js_code=" + code
                + "&grant_type=" + GlobalsConstants.GRANT_TYPE;
        String sr = HttpCallOtherInterfaceUtils.callOtherInterface(GlobalsConstants.CODE_URL, "?" + params);
        Map<String, Object> result = JSON.parseObject(sr);
        return result;
    }

工具类

    String CODE_URL = "https://api.weixin.qq.com/sns/jscode2session";

    String GRANT_TYPE = "authorization_code";

/**
 * @author: LHL
 */
public class HttpCallOtherInterfaceUtils {

    private static final Logger logger = LoggerFactory.getLogger(HttpCallOtherInterfaceUtils.class);


    public static String callOtherPostInterface(JSONObject jsonParam, String gatewayUrl, String postUrl) {
        HttpClient client = HttpClients.createDefault();
        // 要调用的接口方法
        String url = gatewayUrl + postUrl;
        HttpPost post = new HttpPost(url);
        JSONObject jsonObject = null;
        try {
            StringEntity s = new StringEntity(jsonParam.toString(), "UTF-8");
            s.setContentType("application/json");
            post.setEntity(s);
            post.addHeader("content-type", "application/json;charset=UTF-8");
            HttpResponse res = client.execute(post);
            if (res.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                // 返回json格式:
                jsonObject = JSONObject.parseObject(EntityUtils.toString(res.getEntity()));
            }
        } catch (Exception e) {
            logger.debug("服务间接口调用出错!");
            e.printStackTrace();
        }
        return null == jsonObject?"":jsonObject.toString();
    }
    public static String callOtherInterface(String gatewayUrl, String getUrl) {
        HttpClient client = HttpClients.createDefault();
        // 要调用的接口方法
        String url = gatewayUrl + getUrl;
        HttpPost get = new HttpPost(url);
        JSONObject jsonObject = null;
        try {
            HttpResponse res = client.execute(get);
            if (res.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                // 返回json格式:
                jsonObject = JSONObject.parseObject(EntityUtils.toString(res.getEntity()));
            }
        } catch (Exception e) {
            logger.debug("服务间接口调用出错!");
            e.printStackTrace();
        }
        return null == jsonObject?"":jsonObject.toString();
    }
    public static String callOtherGetInterface(String gatewayUrl, String getUrl) {
        HttpClient client = HttpClients.createDefault();
        // 要调用的接口方法
        String url = gatewayUrl + getUrl;
        HttpGet get = new HttpGet(url);
        JSONObject jsonObject = null;
        try {
            HttpResponse res = client.execute(get);
            if (res.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                // 返回json格式:
                jsonObject = JSONObject.parseObject(EntityUtils.toString(res.getEntity()));
            }
        } catch (Exception e) {
            logger.debug("服务间接口调用出错!");
            e.printStackTrace();
        }
        return null == jsonObject?"":jsonObject.toString();
    }
}
		

/**
 * 微信授权access_token获取
 *
 * @author LHL
 */
public interface AccessTokenService {
    /**
     * 获取缓存
     *
     * @param key key
     * @author LHL
     */
    Object getCache(String key);

    /**
     * 设置缓存
     *
     * @param key        key
     * @param value      值
     * @param expireTime 秒
     * @author LHL
     */
    boolean setCache(String key, Object value, Long expireTime);

    /**
     * key是否存在
     *
     * @param key key
     * @author LHL
     */
    boolean exists(final String key);

    /**
     * 获取access_token
     *
     * @author LHL
     */
    Map<String, Object> getAccessToken();

}


/**
 * 微信授权access_token获取
 *
 * @author LHL
 */
@Service
public class AccessTokenServiceImpl implements AccessTokenService {
    private final static String API_URL = "https://api.weixin.qq.com/cgi-bin/token";
    private final static String GRANT_TYPE = "client_credential";

    @Value("${wx.appid}")
    private String appid;

    @Value("${wx.appsecret}")
    private String appSecret;

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    public Object getCache(String key){
        Object result = null;
        ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
        result = operations.get(key);
        return result;
    }

    @Override
    public boolean setCache(String key, Object value, Long expireTime){
        boolean result = false;
        try {
            ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
            operations.set(key, value);
            redisTemplate.expire(key, expireTime, TimeUnit.SECONDS);
            result = true;
        }
        catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    @Override
    public boolean exists(final String key) {
        try {

            boolean result=redisTemplate.hasKey(key);
            return result;
        }
        catch (Exception e) {
            return false;
        }
    }

    @Override
    public Map<String, Object> getAccessToken(){
        String params = "grant_type=" + GRANT_TYPE + "&appid=" + appid + "&secret=" + appSecret;
        String reStr = restTemplate.getForObject(API_URL + "?" + params, String.class);
        JSONObject result = JSONObject.parseObject(reStr);
        if(result.containsKey("access_token")){
            Map<String, Object> map = new HashMap<>();
            map.put("token", result.get("access_token").toString());
            map.put("expires_time", result.get("expires_in"));
            return map;
        }
        return null;
    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值