Java微信登录案例怎么编写

wen java案例 31

本文目录导读:

Java微信登录案例怎么编写

  1. 整体流程
  2. 后端Java实现
  3. 前端调用示例(微信小程序)
  4. 注意事项

我来为你提供一个完整的Java微信登录案例,这个案例会包含服务端的主要逻辑代码。

整体流程

  1. 前端获取微信授权code
  2. 后端用code换取access_token和openid
  3. 获取用户信息
  4. 生成业务token返回给前端

后端Java实现

添加依赖(pom.xml)

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>2.0.32</version>
</dependency>
<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
    <version>4.5.14</version>
</dependency>

微信配置类

@Component
@ConfigurationProperties(prefix = "wechat")
@Data
public class WechatConfig {
    // 微信小程序appId
    private String appId;
    // 微信小程序secret
    private String secret;
    // 微信登录凭证校验接口
    private String code2SessionUrl = "https://api.weixin.qq.com/sns/jscode2session";
    // 获取access_token接口
    private String accessTokenUrl = "https://api.weixin.qq.com/cgi-bin/token";
    // 获取用户信息接口
    private String userInfoUrl = "https://api.weixin.qq.com/cgi-bin/user/info";
}

application.yml配置

wechat:
  app-id: your_appid
  secret: your_secret

微信登录服务类

@Service
@Slf4j
public class WechatLoginService {
    @Autowired
    private WechatConfig wechatConfig;
    @Autowired
    private StringRedisTemplate redisTemplate;
    /**
     * 微信登录主方法
     * @param code 前端获取的临时code
     * @return 登录结果
     */
    public LoginResult login(String code) {
        try {
            // 1. 用code获取session_key和openid
            WxSession session = getSessionKey(code);
            if (session == null || session.getOpenid() == null) {
                return LoginResult.fail("获取微信session失败");
            }
            // 2. 查询或创建用户
            User user = findOrCreateUser(session.getOpenid());
            // 3. 生成业务token
            String token = generateToken(user);
            // 4. 返回登录结果
            return LoginResult.success(token, user);
        } catch (Exception e) {
            log.error("微信登录失败", e);
            return LoginResult.fail("登录失败");
        }
    }
    /**
     * 通过code获取session
     */
    private WxSession getSessionKey(String code) {
        String url = String.format("%s?appid=%s&secret=%s&js_code=%s&grant_type=authorization_code",
                wechatConfig.getCode2SessionUrl(),
                wechatConfig.getAppId(),
                wechatConfig.getSecret(),
                code);
        String result = HttpClientUtil.doGet(url);
        WxSession session = JSON.parseObject(result, WxSession.class);
        if (session.getErrcode() != null && session.getErrcode() != 0) {
            log.error("微信登录失败: {}", result);
            return null;
        }
        return session;
    }
    /**
     * 获取微信用户信息(如需获取昵称、头像等)
     */
    public WxUserInfo getWxUserInfo(String accessToken, String openid) {
        String url = String.format("%s?access_token=%s&openid=%s&lang=zh_CN",
                wechatConfig.getUserInfoUrl(),
                accessToken,
                openid);
        String result = HttpClientUtil.doGet(url);
        return JSON.parseObject(result, WxUserInfo.class);
    }
    /**
     * 查询或创建用户
     */
    private User findOrCreateUser(String openid) {
        // 查询数据库,这里用伪代码表示
        User user = userMapper.findByOpenid(openid);
        if (user == null) {
            // 创建新用户
            user = new User();
            user.setOpenid(openid);
            user.setNickname("微信用户");
            user.setCreateTime(new Date());
            userMapper.insert(user);
        }
        return user;
    }
    /**
     * 生成token
     */
    private String generateToken(User user) {
        // 使用JWT或UUID生成token
        String token = UUID.randomUUID().toString().replace("-", "");
        // 存储到redis,设置过期时间
        redisTemplate.opsForValue().set(
            "token:" + token, 
            JSON.toJSONString(user), 
            7, // 7天过期
            TimeUnit.DAYS
        );
        return token;
    }
}

用户实体类

@Data
public class User {
    private Long id;
    private String openid;
    private String nickname;
    private String avatar;
    private Date createTime;
    private Date updateTime;
}

微信会话对象

@Data
public class WxSession {
    private String openid;
    private String sessionKey;
    private String unionid;
    private Integer errcode;
    private String errmsg;
}

用户信息对象

@Data
public class WxUserInfo {
    private String openid;
    private String nickname;
    private Integer sex;
    private String province;
    private String city;
    private String country;
    private String headimgurl;
    private String unionid;
}

登录结果封装

@Data
@AllArgsConstructor
@NoArgsConstructor
public class LoginResult {
    private boolean success;
    private String token;
    private User user;
    private String message;
    public static LoginResult success(String token, User user) {
        return new LoginResult(true, token, user, null);
    }
    public static LoginResult fail(String message) {
        return new LoginResult(false, null, null, message);
    }
}

HTTP工具类

@Component
public class HttpClientUtil {
    public static String doGet(String url) {
        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpGet httpGet = new HttpGet(url);
        try {
            CloseableHttpResponse response = httpClient.execute(httpGet);
            if (response.getStatusLine().getStatusCode() == 200) {
                return EntityUtils.toString(response.getEntity(), "UTF-8");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}

控制器

@RestController
@RequestMapping("/api/wechat")
public class WechatLoginController {
    @Autowired
    private WechatLoginService wechatLoginService;
    /**
     * 微信登录接口
     */
    @PostMapping("/login")
    public Result login(@RequestParam String code) {
        LoginResult loginResult = wechatLoginService.login(code);
        if (loginResult.isSuccess()) {
            return Result.success(loginResult);
        }
        return Result.error(loginResult.getMessage());
    }
    /**
     * 验证token是否有效
     */
    @GetMapping("/verify")
    public Result verifyToken(@RequestHeader("Authorization") String token) {
        // 验证token逻辑
        return Result.success();
    }
}

前端调用示例(微信小程序)

// pages/login/login.js
Page({
  data: {},
  // 微信登录按钮点击事件
  wechatLogin: function() {
    wx.login({
      success: (res) => {
        if (res.code) {
          // 调用后端接口
          wx.request({
            url: 'https://your-api.com/api/wechat/login',
            method: 'POST',
            data: {
              code: res.code
            },
            success: (response) => {
              if (response.data.success) {
                // 存储token
                wx.setStorageSync('token', response.data.data.token);
                // 登录成功跳转
                wx.navigateBack();
              } else {
                wx.showToast({
                  title: '登录失败',
                  icon: 'none'
                });
              }
            }
          });
        }
      }
    });
  }
});

注意事项

  1. code只能使用一次,每次登录都需要前端重新获取
  2. session_key 不应该传给前端,只在服务端使用
  3. 建议使用 HTTPS 协议保证数据传输安全
  4. token过期时间 根据业务需求设置
  5. 用户信息建议使用 缓存 减少数据库查询

这个案例提供了完整的微信登录后端实现,你可以根据实际业务需求进行调整和扩展。

抱歉,评论功能暂时关闭!