Java架构学习(四十九)会员登录与注册项目回顾&发送邮件功能实现&移动APP端token登录实现

一、项目回顾

会员注册流程

在这里插入图片描述

会员注册的时候,通过MQ异步推送邮件有什么好处?
答:因为通过传统的http来进行同步来推送,是非常耗费时间的,
有时候也会因为网络问题而影响了注册的流程。这个时候我们只需要通过
MQ进行缓存消息,然后异步推送消息,就可以保证消息的一致性。

公司消息服务平台主要是处理什么业务的?
答:消息服务平台主要处理公司内部消息请求,比如发送邮件、
发送短信、微信发送。

难点:
1、消息服务平台进行推送邮件
2、登录:要支持多端登录、移动APP登录设计
	使用token令牌进行登录。token存放在redis中,设置有效期为90天等。

问题:
消费者宕机了而且没有高可用的情况下,生产者一直发送消息会怎么处理?
答:使用MQ缓存机制将生产者生产的消息存放在MQ消息队列中,采用持久化存储。
等重启消费者后再使用MQ进行消息推送。

二、发送邮件功能

大公司发送邮件是自己单间邮件服务器的或者去购买邮件服务器
package com.leeue.email.service;

import javax.security.auth.Subject;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSONObject;
import com.leeue.adapter.MessageAdapter;

import lombok.extern.slf4j.Slf4j;

/**
 * @classDesc: 功能描述:(发送邮件  实现  主要是处理调用第三方接口发送邮件)
 * @author:<a href="leeue@foxmail.com">李月</a>
 * @Version:v1.0
 * @createTime:2018年12月19日 下午3:35:22
 */
@Service
@Slf4j
public class EmailService implements MessageAdapter{

	/**
	 * 发送邮件的主题
	 */
	@Value("${msg.subject}")
	private String subject;
	/**
	 * 发送邮件的内容
	 */
	@Value("${msg.text}")
	private String text;
	/**
	 * 发送邮件
	 */
	@Autowired
	private JavaMailSender javaMailSender;
	
	/**
	 * 发送邮件服务器
	 */
	@Value("${fromEmail}")
	private String fromEmail;
	
	@Override
	public void sendMsg(JSONObject body) {
		//处理发送邮件的
		String email = body.getString("email");
		if(StringUtils.isEmpty(email)) {
			return;
		}
		log.info("消息服务平台发送邮件到....:{}",email);
		
		//发送邮件 SpringBoot已经封装好了
		SimpleMailMessage simpleMailMessage = new SimpleMailMessage();
		//这里测试我们是自己给自己发送邮件
		log.info("####消息服务平台发送邮件到:{}开始",email);
		//来自账号:发件人
		simpleMailMessage.setFrom(fromEmail);
		//要发送的的账号
		simpleMailMessage.setTo(email);
		//标题
		simpleMailMessage.setSubject(subject);
		//发送内容  {} 替换这个字符变成email
		simpleMailMessage.setText(text.replace("{}", email));

		javaMailSender.send(simpleMailMessage);
		log.info("####消息服务平台发送邮件到:{}成功",email);
	}

}

三、移动App登录

1、多端登录SSO

移动端登录是使用token方式进行登录的
pc端是跟根据session、cookie来保证会话信息的。

移动端登录使用token登录方案:
1、移动过端调用登录接口传入参数用户名称和登录密码
2、服务器端收到客户端传入的参数进行数据验证,如果服务器端
验证正确进行3
3、验证正确把用户信息存放在redis中,
其中token 为key  value 为用户的ID userID
4、什么是token?只是一个令牌、临时唯一的。
5、服务器返回token给客户端,客户端拿到token后,存放在本地
6、移动端调用服务器使用token查询用户信息
7、查询用户信息的接口是通过移动端传过来的token查找redis
	取出userID,通过userID来查数据库里面用户信息。返回用户信息
	给客户端。

登录部分代码:注意里面存放的redis配置上次已经放到了配置文件中了。
	@Override
	public ResponseBase login(@RequestBody UserEntity user) {
		//1.验证传来的参数
		String username = user.getUsername();
		String password = user.getPassword();
		if(StringUtils.isEmpty(username)) {
			return setResultError("用户名为空!");
		}
		if(StringUtils.isEmpty(password)) {
			return setResultError("密码为空!");
		}
		//2.数据库查找账号和密码是否正确
		String newPassword = MD5Util.MD5(password);
		UserEntity userEntity = memberDao.login(username, newPassword);
		if(userEntity == null) {
			return setResultError("账号或者密码不正确");
		}
		//3.如果账号密码正确,对应生成token
		String memberToken = TokenUtils.getMemberToken();
		//4.存放在redis中,key为token value为用户的userid
		Integer userId = userEntity.getId();
		log.info("####用户信息存放在了redis中#### key=:{},value=:{}",memberToken,userId);
		baseRedisService.setString(memberToken, userId+"", Constants.tOKEN_MEMBER_TIME_OUT);
		//将token封装在json对象里面去
		JSONObject jsonObject = new JSONObject();
		jsonObject.put("memberToken", memberToken);
		//5.返回结果
		return setResultSuccess(jsonObject);
	}

使用token来查询用户的信息
@Override
	public ResponseBase findByTokenUser(String token) {
		//1.验证参数
		if(StringUtils.isEmpty(token)) {
			return setResultError("token不能为空");
		}
		//2.从redis中使用token查找对应的userid
		String userIdStr = (String) baseRedisService.getString(token);
		if(StringUtils.isEmpty(userIdStr)) {
			return setResultError("该用户的token信息不存在");
		}
		Long userId = Long.valueOf(userIdStr);
		//3.拿到了userid 从数据库中通过userid来查找当前的用户信息并且返回
		UserEntity userEntity = memberDao.findByID(userId);
		if(userEntity == null) {
			return setResultError("该用户信息不存在");
		}
		//为了安全,查询到的密码不能被返回
		userEntity.setPassword(null);
		//4.返回当前的user信息,
		JSONObject  jsonObject = new JSONObject();
		jsonObject.put("userInfo", userEntity);
		
		return setResultSuccess(jsonObject);
	}

在企业项目中,用户表肯定有许多数据,要加个字段来判断当前的用户信息有没有存放在redis中。
如果已经存在redis中就可以查到当前的用户信息,如果已经有了,用户又登录了。可以通过
这个状态值,覆盖掉当前存放在redis中的值。

这个是移动端的会话token,类似web端的的session.
在做核心业务的时候一定要使用手机验证码来验证。
确保是真实身份来做该操作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值