后端:四个接口(注册接口、获取验证码接口、登录接口、获取用户信息接口)
验证码接口(此处短信发送默认成功且验证码为1111,实际上未发送)
@Autowired
private MsmService msmService;
@Autowired
private RedisTemplate<String,String> redisTemplate;
//发送短信方法
@GetMapping("send/{phone}")
public R sendMsm(@PathVariable String phone){
//从redis获取验证码
String code = redisTemplate.opsForValue().get(phone);
if (!StringUtils.isEmpty(code)){
return R.ok();
}
//生成随机值,传递到阿里云进行发送
// code = RandomUtil.getFourBitRandom();发送短信验证码为1111
code = "1111";
Map<String,Object> param = new HashMap<>();
param.put("code",code);
// boolean isSend = msmService.send(param,phone); 默认发生成功
boolean isSend = true;
if (isSend){
//设置redis中存储数据的时长,电话号/验证码/时间/时间单位
redisTemplate.opsForValue().set(phone,code,5, TimeUnit.MINUTES);
return R.ok();
}
else {
return R.error().message("短信发送失败");
}
}
service层
@Service
public class MsmServiceImpl implements MsmService {
@Override
public boolean send(Map<String, Object> param, String phone) {
//传入map 包含code与随机验证码 手机号
//如果手机号为空
if(StringUtils.isEmpty(phone)) return false;
//传入阿里云的keyid与secret 地区为默认
DefaultProfile profile =
DefaultProfile.getProfile("default", "不能告诉你keyid", "不能告诉你secret ");
IAcsClient client = new DefaultAcsClient(profile);
//设置相关固定参数
CommonRequest request = new CommonRequest();
request.setMethod(MethodType.POST);
request.setDomain("dysmsapi.aliyuncs.com");
request.setVersion("2017-05-25");
request.setAction("SendSms");
//设置发送相关参数
request.putQueryParameter("PhoneNumbers",phone);//手机号
request.putQueryParameter("SignName","我的Aokil博客");//申请阿里云 签名名称
request.putQueryParameter("TemplateCode","SMS_210065560");//申请阿里云 模板名称
request.putQueryParameter("TemplateParam", JSONObject.toJSONString(param));//申请阿里云 验证码
try {
CommonResponse response = client.getCommonResponse(request);
boolean success = response.getHttpResponse().isSuccess();
return success;
}catch (Exception e){
}
return false;
}
}
注册接口
//根据验证码实现注册(验证码接口另调用)
@PostMapping("register")
public R registerUser(@RequestBody RegisterVo registerVo){
memberService.register(registerVo);
return R.ok();
}
service
public void register(RegisterVo registerVo) {
String code = registerVo.getCode();
String mobile = registerVo.getMobile();
String nickname = registerVo.getNickname();
String password = registerVo.getPassword();
//判断四项是否为空
if (StringUtils.isEmpty(code)||
StringUtils.isEmpty(mobile)||
StringUtils.isEmpty(nickname)||
StringUtils.isEmpty(password)){
throw new GuliException(20001,"注册失败");
}
//判断验证码
String redisCodes= redisTemplate.opsForValue().get(mobile);
if (!code.equals(redisCodes)){
throw new GuliException(20001,"注册失败");
}
//判断手机号是否重复
QueryWrapper<UcenterMember> wrapper = new QueryWrapper<>();
wrapper.eq("mobile",mobile);
Integer integer = baseMapper.selectCount(wrapper);
if(integer>0){
throw new GuliException(20001,"注册失败");
}
UcenterMember member = new UcenterMember();
member.setMobile(mobile);
member.setNickname(nickname);
member.setPassword(MD5.encrypt(password));
member.setIsDisabled(false);
member.setAvatar("https://online-teach-file.oss-cn-beijing.aliyuncs.com/teacher/2019/11/08/e44a2e92-2421-4ea3-bb49-46f2ec96ef88.png");
baseMapper.insert(member);
}
登录接口
//根据手机号和密码登录
@PostMapping("login")
public R loginUser(@RequestBody UcenterMember member){
String token = memberService.login(member);
return R.ok().data("token",token);
}
service层(加密模式为MD5)
public String login(UcenterMember member) {
//获取登录手机号和密码
String mobile = member.getMobile();
String password = member.getPassword();
System.out.println(member);
//判断用户名密码是否为空
if (StringUtils.isEmpty(mobile)||StringUtils.isEmpty(password)){
throw new GuliException(20001,"登录失败");
}
//判断手机号是否正确
QueryWrapper<UcenterMember> wrapper = new QueryWrapper<>();
wrapper.eq("mobile",mobile);
UcenterMember ucenterMember = baseMapper.selectOne(wrapper);
if (ucenterMember == null){
throw new GuliException(20001,"手机号错误");
}
//判断密码
//先进行加密再判断
if(!MD5.encrypt(password).equals(ucenterMember.getPassword())){
throw new GuliException(20001,"密码错误");
}
//判断用户是否禁用
if (ucenterMember.getIsDisabled()){
throw new GuliException(20001,"用户被禁用");
}
//登录成功
//生成token字符串,使用jwt工具类,返回id与昵称
String jwtToken = JwtUtils.getJwtToken(ucenterMember.getId(), ucenterMember.getNickname());
return jwtToken;
}
MD5工具类
public final class MD5 {
public static String encrypt(String strSrc) {
try {
char hexChars[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8',
'9', 'a', 'b', 'c', 'd', 'e', 'f' };
byte[] bytes = strSrc.getBytes();
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(bytes);
bytes = md.digest();
int j = bytes.length;
char[] chars = new char[j * 2];
int k = 0;
for (int i = 0; i < bytes.length; i++) {
byte b = bytes[i];
chars[k++] = hexChars[b >>> 4 & 0xf];
chars[k++] = hexChars[b & 0xf];
}
return new String(chars);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
throw new RuntimeException("MD5加密出错!!+" + e);
}
}
public static void main(String[] args) {
System.out.println(MD5.encrypt("111111"));
}
}
根据Token获取用户信息接口(使用JWT获取Token中的信息)
//根据token获取用户信息
@GetMapping("getMemberInfo")
public R getMemberInfo(HttpServletRequest request){
String memberId= JwtUtils.getMemberIdByJwtToken(request);
UcenterMember member = memberService.getById(memberId);
return R.ok().data("userInfo",member);
}
JWTUtils
public class JwtUtils {
public static final long EXPIRE = 1000 * 60 * 60 * 24;//token过期时间
public static final String APP_SECRET = "ukc8BDbRigUDaY6pZFfWus2jZWLPHO";//秘钥
//生成token字符串的方法
public static String getJwtToken(String id, String nickname){
String JwtToken = Jwts.builder()
.setHeaderParam("typ", "JWT")
.setHeaderParam("alg", "HS256")
.setSubject("aokill-user")
//设置过期时间
.setIssuedAt(new Date())
.setExpiration(new Date(System.currentTimeMillis() + EXPIRE))
//设置token的主体部分,用来存储用户信息
.claim("id", id)
.claim("nickname", nickname)
//签名hash
.signWith(SignatureAlgorithm.HS256, APP_SECRET)
.compact();
return JwtToken;
}
/**
* 判断token是否存在与有效
* @param jwtToken
* @return
*/
public static boolean checkToken(String jwtToken) {
if(StringUtils.isEmpty(jwtToken)) return false;
try {
Jwts.parser().setSigningKey(APP_SECRET).parseClaimsJws(jwtToken);
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}
/**
* 判断token是否存在与有效
* @param request
* @return
*/
public static boolean checkToken(HttpServletRequest request) {
try {
String jwtToken = request.getHeader("token");
if(StringUtils.isEmpty(jwtToken)) return false;
Jwts.parser().setSigningKey(APP_SECRET).parseClaimsJws(jwtToken);
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}
/**
* 根据token获取会员id
* @param request
* @return
*/
public static String getMemberIdByJwtToken(HttpServletRequest request) {
String jwtToken = request.getHeader("token");
if(StringUtils.isEmpty(jwtToken)) return "";
Jws<Claims> claimsJws = Jwts.parser().setSigningKey(APP_SECRET).parseClaimsJws(jwtToken);
Claims claims = claimsJws.getBody();
return (String)claims.get("id");
}
}
四个接口写好了,现在开始前端的流程
前端 根据Token获取用户信息
- 1.调用登录接口 登录成功返回Token字符串
- 2.把第一步返回的Token字符串放入Cookie里
- 3.创建前端拦截器,判断Cookie里面是否有Token字符串,如果有,把Token字符串放入header请求头中
- 4.根据Token值,调用接口,根据token获取用户信息,把返回的信息放到cookie中
- 5.在页面显示用户信息,从第四步cookie获取用户信息
登录的方法
API
//登录的方法
submitLoginUser(member) {
return request({
url: `/educenter/member/login`,
method: 'post',
data:member
})
},
//获取Token中信息的方法
getLoginUserInfo() {
return request({
url: `/educenter/member/getMemberInfo`,
method: 'get'
})
},
页面中
methods: {
//登录的方法
submitLogin(){
//第一步进行接口调用,返回token字符串
login.submitLoginUser(this.user)
.then(response =>{
//第二步 获取token字符串放到cookie中
//第一个参数是cookie名称,第二个参数值,第三个参数作用范围
cookie.set('guli_token',response.data.data.token,{domain:'localhost'})
//第四部 调用接口 根据token获取用户信息,为了首页面显示
loign.getLoginUserInfo()
.then(response => {
this.loginInfo = response.data.data.userInfo
//获取返回用户信息,放到cookie中
cookie.set('aokill_ucenter',this.loginInfo,{domain:'localhost'})
})
window.location.href = "/";
})
}
}
第三步的拦截器要放在request.js中,因为每个api都会导入request.js
import axios from 'axios'
import { MessageBox, Message } from 'element-ui'
import cookie from 'js-cookie'
// 创建axios实例
const service = axios.create({
baseURL: 'http://localhost:9001', // api的base_url
timeout: 20000 // 请求超时时间
})
//拦截器 如果有cookie值 则放到请求头中
service.interceptors.request.use(
config => {
if(cookie.get('aokill_token')){
config.headers['token'] = cookie.get('aokill_token');
}
return config
},
err => {
return Promise.reject(err);
})
//------
export default service
那么如何在页面中获取数据呢?记得导入js-cookie
import cookie from 'js-cookie'
created(){
this.showInfo()
},
methods:{
//创建方法,从cookie获取用户信息
showInfo(){
//从cookie获取用户信息
var userStr = cookie.get('aokill_ucenter')
//把字符串转换成json对象
if(userStr){
this.loginInfo = JSON.parse(userStr)
}
}
}