当前位置: 首页 > news >正文

苏州营销型网站网络营销推广方案前言

苏州营销型网站,网络营销推广方案前言,网上书城网站开发环境,规划网站的总结项目介绍 导入黑马点评项目 项目架构 基于Session实现登录 基本流程 实现发送短信验证码功能 controller层中 /*** 发送手机验证码*/PostMapping("code")public Result sendCode(RequestParam("phone") String phone, HttpSession session) {// 发送短信…

项目介绍

导入黑马点评项目

项目架构

 

 

基于Session实现登录

基本流程

实现发送短信验证码功能

 controller层中

    /*** 发送手机验证码*/@PostMapping("code")public Result sendCode(@RequestParam("phone") String phone, HttpSession session) {//  发送短信验证码并保存验证码return userService.sendCode(phone,session);}

Service层中

真的发送的话要接入阿里云或腾讯云的短信发送功能,这里假装发送成功。

@Slf4j
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {@Overridepublic Result sendCode(String phone, HttpSession session) {//1.校验手机号if(RegexUtils.isPhoneInvalid(phone)){//2.如果不符合,返回错误信息return Result.fail("手机号格式错误!");}//3.符合,生成验证码String code = RandomUtil.randomNumbers(6);//4.保存验证码session.setAttribute("code",code);//5.发送验证码log.debug("发送短信验证码成功,验证码:{}",code);return Result.ok();}
}

再次点击发送就可以看见如下:

 

实现验证码登录和注册功能

Controller层中

    /*** 登录功能* @param loginForm 登录参数,包含手机号、验证码;或者手机号、密码*/@PostMapping("/login")public Result login(@RequestBody LoginFormDTO loginForm, HttpSession session){// 实现登录功能return userService.login(loginForm,session);}

Service层中

    @Overridepublic Result login(LoginFormDTO loginForm, HttpSession session) {//1.验证手机号String phone=loginForm.getPhone();if(RegexUtils.isPhoneInvalid(phone)){//1.1不符合,返回报错return Result.fail("手机号格式错误!");}//2.校验验证码Object cacheCode = session.getAttribute("code");String code = loginForm.getCode();if(cacheCode==null||!cacheCode.toString().equals(code)){//3.不一致,报错return Result.fail("验证码错误");}//4.一致,根据手机号查询用户 select * from tb_user where phone=?User user = query().eq("phone", phone).one();//5.判断用户是否存在if(user==null){//6.不存在,创建新用户并保存user=   createUserWithPhone(phone);}//7.存在,保存用户信息到session中session.setAttribute("user",user);return Result.ok();}private User createUserWithPhone(String phone) {//1.创建用户User user=new User();user.setPhone(phone);user.setNickName(USER_NICK_NAME_PREFIX+RandomUtil.randomString(10));//2.保存save(user);return user;}

这里的session之所以能够获取到发送验证码请求时存入的验证码是因为这是在同一个会话当中,session会被返回给前端,下一次请求也会携带同一个session过来。所以才有之前保存的信息在里面。

实现登录校验拦截器

 

 接口多了之后就要拦截器进行统一校验,然后为了传递用户信息给后序的业务,需要将用户信息存入Threadlocal里面的.Threadlocal是每个请求线程的一个独立保存空间。

在拦截器的最后一个方法中,清空thread local的信息,第一可以做到退出登录,第二可以防止内存泄露

新建一个拦截器

public class LoginInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {//1.获取sessionHttpSession session = request.getSession();//2.获取session中的用户Object user = session.getAttribute("user");//3.判断用户是否存在if(user==null){//4.不存在,拦截response.setStatus(401);return false;}//5.存在,保存用户信息到ThreadLocalUserHolder.saveUser((UserDTO) user);//6.放行return true;}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {//移除用户UserHolder.removeUser();}
}

 新建配置项

将上面的拦截器投入使用,并且指定不拦截的请求。

@Configuration
public class MvcConfig implements WebMvcConfigurer {@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new LoginInterceptor()).excludePathPatterns("/shop/**","/shop-type/**","/upload/**","/blog/hot","/user/code" ,"/user/login");}
}

登录校验接口

    @GetMapping("/me")public Result me(){// 获取当前登录的用户并返回UserDTO user= UserHolder.getUser();return Result.ok(user);}

隐藏用户敏感信息

在前面代码里返回给前端的是用户完整信息,这是不合理的,所以改成如下。

在session存的时候就只存部分信息。然后上面登录校验逻辑因为黑马资料的问题已经是隐藏之后的了的,所以只改这里一个地方即可。

    @Overridepublic Result login(LoginFormDTO loginForm, HttpSession session) {........//7.存在,保存用户信息到session中session.setAttribute("user", BeanUtil.copyProperties(user, UserDTO.class));return Result.ok();}

集群的session共享问题

使用Redis解决Session共享问题。 

基于Redis实现共享session登录

业务流程

基于redis实现短信登录

发送短信验证码部分的代码修改:

生成验证码之后将验证码存入Redis

    @Resourceprivate StringRedisTemplate stringRedisTemplate;@Overridepublic Result sendCode(String phone, HttpSession session) {//1.校验手机号...//3.符合,生成验证码...//4.保存验证码到RedisstringRedisTemplate.opsForValue().set("login:code:"+phone,code,2, TimeUnit.MINUTES);//5.发送验证码...}

短信验证码登录,注册功能部分的代码修改:

    @Overridepublic Result login(LoginFormDTO loginForm, HttpSession session) {//1.验证手机号...//  2.从redis获取 校验验证码String cacheCode = stringRedisTemplate.opsForValue().get(LOGIN_CODE_KEY+phone);...//4.一致,根据手机号查询用户 select * from tb_user where phone=?...//5.判断用户是否存在...//7.存在,保存用户信息到Redis中//7.1.随机生成token,作为登录令牌String token = UUID.randomUUID().toString(true);//7.2将User对象转为Hash存储UserDTO userDTO=BeanUtil.copyProperties(user, UserDTO.class);Map<String, Object> userMap = BeanUtil.beanToMap(userDTO);//7.3存储String tokenKey="login::token:"+token;stringRedisTemplate.opsForHash().putAll(tokenKey,userMap);//7.4设置token有效期stringRedisTemplate.expire(tokenKey,30,TimeUnit.MINUTES);//8.返回tokenreturn Result.ok(token);}

登录拦截器代码修改


public class LoginInterceptor implements HandlerInterceptor {private StringRedisTemplate stringRedisTemplate;public LoginInterceptor(StringRedisTemplate stringRedisTemplate) {this.stringRedisTemplate=stringRedisTemplate;}@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {//1.获取请求头中的tokenString token = request.getHeader("authorization");if (StrUtil.isBlank(token)) {//4.不存在,拦截response.setStatus(401);return false;}//2.基于token获取redis中的用户String tokenKey=RedisConstants.LOGIN_USER_KEY + token;Map<Object, Object> userMap = stringRedisTemplate.opsForHash().entries(tokenKey);//3.判断用户是否存在if(userMap.isEmpty()){//4.不存在,拦截response.setStatus(401);return false;}//5.将查询到的Hash数据转为UserDTO对象UserDTO userDTO = BeanUtil.fillBeanWithMap(userMap, new UserDTO(), false);//6.存在,保存用户信息到ThreadLocalUserHolder.saveUser( userDTO);//7.刷新token有效期stringRedisTemplate.expire(tokenKey,RedisConstants.CACHE_SHOP_TTL, TimeUnit.MINUTES);//8.放行return true;}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {//移除用户...}
}

因为这里不能用注解注入stringRedisTemplate,要在MVC配置器哪里进行注入

@Configuration
public class MvcConfig implements WebMvcConfigurer {@Resourceprivate StringRedisTemplate stringRedisTemplate;@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new LoginInterceptor(stringRedisTemplate)).excludePathPatterns("/shop/**","/shop-type/**","/upload/**","/blog/hot","/user/code" ,"/user/login");}
}

出现Long转String的报错 

在登录逻辑里面将对象转为Map时做多点工作

        //7.2将User对象转为Hash存储UserDTO userDTO=BeanUtil.copyProperties(user, UserDTO.class);Map<String, Object> userMap = BeanUtil.beanToMap(userDTO,new HashMap<>(),CopyOptions.create().setIgnoreNullValue(true).setFieldValueEditor((fieldName,fieldValue)->fieldValue.toString()));

 可以看见对应东西

 

解决登录状态刷新问题

登录状态的刷新只会在访问需要拦截的请求时才刷新,如果是不需要拦截的请求就不会刷新.

为了拦截所有请求,这里新加一个拦截器

新增刷新拦截器:

public class RefreshTokenInterceptor implements HandlerInterceptor {private StringRedisTemplate stringRedisTemplate;public RefreshTokenInterceptor(StringRedisTemplate stringRedisTemplate) {this.stringRedisTemplate=stringRedisTemplate;}@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {//1.获取请求头中的tokenString token = request.getHeader("authorization");if (StrUtil.isBlank(token)) {return true;}//2.基于token获取redis中的用户String tokenKey=RedisConstants.LOGIN_USER_KEY + token;Map<Object, Object> userMap = stringRedisTemplate.opsForHash().entries(tokenKey);//3.判断用户是否存在if(userMap.isEmpty()){return true;}//5.将查询到的Hash数据转为UserDTO对象UserDTO userDTO = BeanUtil.fillBeanWithMap(userMap, new UserDTO(), false);//6.存在,保存用户信息到ThreadLocalUserHolder.saveUser( userDTO);//7.刷新token有效期stringRedisTemplate.expire(tokenKey,RedisConstants.CACHE_SHOP_TTL, TimeUnit.MINUTES);//8.放行return true;}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {//移除用户UserHolder.removeUser();}
}

 修改原本的登录拦截器

public class LoginInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {//1.判断是否需要拦截(ThreadLocal中是否有用户)if(UserHolder.getUser()==null){//没有,需要拦截response.setStatus(401);return false;}return true;}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {//移除用户UserHolder.removeUser();}
}

MVC配置类当中

需要添加order保证刷新拦截器先执行。

@Configuration
public class MvcConfig implements WebMvcConfigurer {@Resourceprivate StringRedisTemplate stringRedisTemplate;@Overridepublic void addInterceptors(InterceptorRegistry registry) {//登录拦截器registry.addInterceptor(new LoginInterceptor()).excludePathPatterns("/shop/**","/shop-type/**","/upload/**","/blog/hot","/user/code" ,"/user/login").order(1);//刷新拦截器registry.addInterceptor(new RefreshTokenInterceptor(stringRedisTemplate)).addPathPatterns("/**").order(0);}
}

http://www.hkea.cn/news/658954/

相关文章:

  • 怎么用自己的电脑做网站服务器产品推广平台排行榜
  • 中国做的比较好的电商网站有哪些哈市今日头条最新
  • 微信怎么做网站推广百度网站优化培训
  • 网站开发支持多个币种电子技术培训机构
  • 移动网站设计与制作怎么找关键词
  • 国内移动端网站做的最好的厦门人才网597人才网
  • 建网站收费吗aso关键词覆盖优化
  • 西安的网站设计与制作首页微信视频号怎么推广引流
  • 顺义公司建站多少钱pc端百度
  • wordpress收费资源下载关键词优化的策略
  • 广州做网站建设的公司网站公司
  • 做网络平台的网站有哪些广州网站维护
  • 网页 代码怎么做网站东莞市民最新疫情
  • 电子商务网站设计中影响客户体验的元素有搜索引擎有哪些种类
  • 网站建设难点优化关键词技巧
  • 免费行情网站链接百度知道合伙人官网
  • 餐饮公司网站建设的特点大数据智能营销
  • 济南快速排名刷关键词排名seo软件
  • 系统做网站的地方百度推广登录后台登录入口
  • 集约化网站建设情况广告公司网站制作
  • 网站制作发票字节跳动广告代理商加盟
  • 义乌做网站武汉seo推广优化公司
  • 济宁哪家网站建设公司正规谷歌浏览器 免费下载
  • 有没有女的做任务的网站广东省新闻
  • seo长尾关键词优化如何做网站推广优化
  • 网站搭建服务合同seo排名赚
  • 东莞有什么比较好的网站公司苏州关键词排名系统
  • 做中国供应商免费网站有作用吗浙江网站推广运营
  • mysql8 wordpress百度推广优化是什么意思
  • 做装修广告网站好seo推广公司招商