一、管理员登录接口
1.业务逻辑见代码:
controller层
@RestController @Slf4j public class AdminController { @Autowired private AdminService adminService; @Autowired private RedisTemplate redisTemplate; /**用户登录*/ @PostMapping("/tokens") public Map<String,String> tokens(@RequestBody Admin admin, HttpSession session) { Map<String, String> result = new HashMap<>(); //转json,fastjson有安全漏洞 推荐用jackson //log.info("接受到admin对象为:{}", JSONUtils.writeJSON(admin)); // 登录 Admin adminDB = adminService.login(admin); // 登录成功,获取token String token = session.getId(); redisTemplate.setKeySerializer(new StringRedisSerializer()); redisTemplate.opsForValue().set(token,adminDB,30, TimeUnit.MINUTES); result.put("token",token); return result; } }
@Service("adminService") @Transactional //控制事务 public class AdminServiceImpl implements AdminService { @Resource private AdminDao adminDao; @Override public Admin login(Admin admin) { //1.根据用户名查用户 Admin adminDB = adminDao.findByUserName(admin.getUsername()); //2.判断用户名是否存在 if(ObjectUtils.isEmpty(adminDB)){ throw new RuntimeException("用户名错误!");} //3.判断密码 String password = DigestUtils.md5DigestAsHex(admin.getPassword().getBytes(StandardCharsets.UTF_8)); if(!StringUtils.equals(password,adminDB.getPassword())){throw new RuntimeException("密码输入错误!");} return adminDB; } }
上边这个是service层,下边这个是mapper文件代码
<!--根据用户名查用户--> <select id="findByUserName" parameterType="String" resultMap="AdminMap"> select id, username, password, avatar, created_at, updated_at, deleted_at from yingxue.admin where username = #{username} </select>
不懂的地方的一些解释。
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.opsForValue().set(token,adminDB,30, TimeUnit.MINUTES)
上边第一句是设置序列化的方式,默认序列化会造成乱码。
第二句是设置的key-string类型,key为token,value为序列化后的admin对象(不止包括账号、密码,还有头像创建时间之类的)。
现在还有一个重要的问题,本题验证登录时用的sessionId作为token,然后把token给返回给浏览器了,有每次访问都得带着这个token来访问。这种做法是算session呢还是token呢,如果是算token的话,为啥用seessionId当token呢。
这里首先我们来看一下cookie、session和token的区别:
cookie和session是一种 追踪 \**客户端\**
与\**服务器端\**
通信的一种方式。
cookie是通过在客户端记录信息(在服务端没有记录)确定用户身份的,而session则通过在服务器端记录信息确定用户身份。
cookie:在客户端请求服务器时,如果服务器需要记录该用户状态就生成一个cookie返回发给客户端的,有客户端浏览器保存cookie,当浏览器再请求该网站时,
浏览器把请求的网址和请求头里的cookie一同提交给服务器 标明自己用户身份和状态。cookie以一段 存储在浏览器中 的文本存在(但服务器中没有保存,所以不够安全)
session : 避免浏览器中可能伪造cookie的不安全,所以 生成并存储 在服务器端的值, 当用户第一次访问服务器时,session在服务器中生成记录并保存,
然后将这个记录通过cookie返回给浏览器,浏览器下次访问时带上cookie,服务器再通过session验证传过来的cookie是否正确。session在用户第一次访
问服务器的时候自动创建。session生成后,只要用户继续访问,服务器就会更新Session的最后访问时间,超时未更新会失效。
注意:cookie是在浏览器端设置过期时间,session是在服务器端设置过期时间。
在session这个设计中,cookie保存的值本质上是什么呢,就是sessionId,每一个session独一无二的。
sessionid: HTTP协议是无状态的,session不能依据HTTP连接来判断是否为同一客户,因此服务器向客户端浏览器发送一个名为SESSIONID的cookie,
它的值为该Session的id。Session依据该cookie来识别是否为同一用户。用户第一次访问会产生一个记录,sessionId保存在session中。
session相比cookie更加安全,但是它还是有缺点,就是每一个用户连接都会在服务器端中产生一个sessionId,当用户很多时会导致服务器压力很大,另外当服务器有多台时还有考虑sessionid在这些服务器之间共享;为了解决这些问题就有了: token 。
当用户第一次登录后,服务器生成一个token并将此token返回给客户端,以后客户端只需带上这个token前来请求数据即可,无需再次带上用户名和密码。 token不保存在session中,服务端在生成token时,加入少量的用户信息,比如用户的id,我们对数据使用算法加密生成签名添加到token中(加密的密钥只有自己知道)传递给客户端,客户端下次访问时带上token,服务器端通过密钥解析token生成签名,比较两次签名是否相同,若不相同则验证失败 简单token的组成;uid(用户唯一的身份标识)、time(当前时间的时间戳)、sign(签名,token的前几位以哈希算法压缩成的一定长度的十六进制字符串。为防止token泄露)。
所以我们每次带的这个东西叫令牌,但是我们还是用token方式来实现登录验证的,验证成功返回请求数据,验证失败让用户重新登录。
二、用户信息接口
即登录成功以后的主界面需要展示用户信息,比如账号、密码、头像等。
这个就简单了,直接传入token,然后再redis中让token做key得到value即可,value即Admin对象,这个接口就很简单了。
标签:总结,浏览器,在线视频,用户,笔记,token,session,cookie,客户端 From: https://www.cnblogs.com/worthmove/p/17003546.html