因为一个App,他借此掌握了约x密码

简介: 因为一个App,他借此掌握了约x密码


最近我的一个朋友独立开发了一个小程序,他给我看了下后台数据,短短几天用户已经20w了,这个小程序不是专对女性,但女性用户却占了2/3,说实话确实有点羡慕。

尤其是那货一副老子掌握了约x密码的欠揍表情,所以最近也在琢磨着要不也开发一个自己的应用。

这个事说难不难,但说简单也没那么简单,就是担心遇到盲区遇到坑,这种东西一多,自己玩着玩着也就没啥信心了。

所以我的计划是先把前端部分需要的东西,常用组件什么的,整体先过一遍,也是捋清思路,对于后端其实还是比较放心,因为我本身就是一直在开发这方面。

前端部分到目前为止还算顺利,整体感觉就是现在的封装好的组件特别多,只要不是非要搞系统上的什么功能应该不太会是什么大麻烦。

到这,本来以为接下来应该会很顺畅了,但是万万没想到最后的最后竟然是后端的东西把我卡了一下...

哪地方呢?开发过登录的同学可能都知道Springsecurity和JWT,这东西我几年前做项目的时候倒是用过,时间一久还是有点生疏了。

于是这两天稍微整理了下,想达到的目的就是能实现注册,能实现登录,能验证登录也能方便调试接口就行,目前就先这样。

所以我继续去找了下网上的资料,毕竟做过还是看几遍就懂了,但是如果让我独立搭一份,估计光pom文件里各种jar包的版本搭配就要调个半天。

算了,还是索性在github上找了一个开源的项目,精简精简就是个脚手架,于是下载了几个高star项目,对比了下发现mail-tiny还不错。

看代码的时候却傻眼了,mail-tiny里对于security的使用和之前找到的资料里的内容似乎不太一样。

不过好在大概逻辑还是一样的,而且代码也更成熟一点。

接下来,我就大概讲下这部分内容

核心

这个项目里springSecurity主要核心还在在它的主配置里

可以通过以下配置来注册自定义JWT权限拦截器,通过定义好的JWT解析器,来验证从header传入的token是否有效

registry.and().addFilterBefore(jwtAuthenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);

验证token

验证token主要使用以下方法,

@Override
    protected void doFilterInternal(HttpServletRequest request,
                                    HttpServletResponse response,
                                    FilterChain chain) throws ServletException, IOException {
        String authHeader = request.getHeader(this.tokenHeader);
        if (authHeader != null && authHeader.startsWith(this.tokenHead)) {
            String authToken = authHeader.substring(this.tokenHead.length());// The part after "Bearer "
            String username = jwtTokenUtil.getUserNameFromToken(authToken);
            LOGGER.info("checking username:{}", username);
            if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
                UserDetails userDetails = this.userDetailsService.loadUserByUsername(username);
                if (jwtTokenUtil.validateToken(authToken, userDetails)) {
                    UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
                    authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
                    LOGGER.info("authenticated user:{}", username);
                    SecurityContextHolder.getContext().setAuthentication(authentication);
                }
            }
        }
        chain.doFilter(request, response);
    }

如果token过期或者因为其他原因失效,则执行以下方法

public class RestAuthenticationEntryPoint implements AuthenticationEntryPoint {
    @Override
    public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Cache-Control","no-cache");
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/json");
        response.getWriter().println(JSONUtil.parse(CommonResult.unauthorized(authException.getMessage())));
        response.getWriter().flush();
    }
}

如果没有权限访问,则会执行以下操作

public class RestfulAccessDeniedHandler implements AccessDeniedHandler{
    @Override
    public void handle(HttpServletRequest request,
                       HttpServletResponse response,
                       AccessDeniedException e) throws IOException, ServletException {
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Cache-Control","no-cache");
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/json");
        response.getWriter().println(JSONUtil.parse(CommonResult.forbidden(e.getMessage())));
        response.getWriter().flush();
    }
}

跨域

同时也可以注册,允许跨域请求

//允许跨域请求的OPTIONS请求
registry.antMatchers(HttpMethod.OPTIONS)
    .permitAll();

可以设置不用token就可以访问的方法

for (String url : ignoreUrlsConfig.getUrls()) {
   registry.antMatchers(url).permitAll();
}

JWT

注册的话也是通过JWT解析器,将密码加密后加到数据库里

public UmsAdmin register(UmsAdminParam umsAdminParam) {
        UmsAdmin umsAdmin = new UmsAdmin();
        BeanUtils.copyProperties(umsAdminParam, umsAdmin);
        umsAdmin.setCreateTime(new Date());
        umsAdmin.setStatus(1);
        //查询是否有相同用户名的用户
        QueryWrapper<UmsAdmin> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(UmsAdmin::getUsername,umsAdmin.getUsername());
        List<UmsAdmin> umsAdminList = list(wrapper);
        if (umsAdminList.size() > 0) {
            return null;
        }
        //将密码进行加密操作
        String encodePassword = passwordEncoder.encode(umsAdmin.getPassword());
        umsAdmin.setPassword(encodePassword);
        baseMapper.insert(umsAdmin);
        return umsAdmin;
    }

登录的话就是验证传入的账号密码是否和数据库里存储的一致,如果一致则返回token。

public String login(String username, String password) {
        String token = null;
        //密码需要客户端加密后传递
        try {
            UserDetails userDetails = loadUserByUsername(username);
            if(!passwordEncoder.matches(password,userDetails.getPassword())){
                Asserts.fail("密码不正确");
            }
            if(!userDetails.isEnabled()){
                Asserts.fail("帐号已被禁用");
            }
            UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
            SecurityContextHolder.getContext().setAuthentication(authentication);
            token = jwtTokenUtil.generateToken(userDetails);
            insertLoginLog(username);
        } catch (AuthenticationException e) {
            LOGGER.warn("登录异常:{}", e.getMessage());
        }
        return token;
    }

目前为止,如果做一般的登录验证应该也就足够了。

mail-tiny的地址如下,有兴趣的可以下出来看看 https://github.com/macrozheng/mall-tiny


相关文章
|
5月前
|
数据安全/隐私保护 Android开发
Android Studio APP实战开发之找回密码及忘记密码(附源码 超实用必看)
Android Studio APP实战开发之找回密码及忘记密码(附源码 超实用必看)
279 0
|
5月前
|
SQL 数据库 数据安全/隐私保护
Android Studio App开发中数据库SQLite的解析及实战使用(包括创建数据库,增删改查,记住密码等 附源码必看)
Android Studio App开发中数据库SQLite的解析及实战使用(包括创建数据库,增删改查,记住密码等 附源码必看)
394 0
|
12月前
|
数据安全/隐私保护 iOS开发
生成IOS app专用密码教程
生成IOS app专用密码教程
|
12月前
|
数据安全/隐私保护 Android开发 iOS开发
解决第三方邮箱APP登陆QQ、163邮箱无法验证账户名或密码的问题(IOS、MacOS、Windows、Android)
解决第三方邮箱APP登陆QQ、163邮箱无法验证账户名或密码的问题(IOS、MacOS、Windows、Android)
200 0
|
数据安全/隐私保护 iOS开发
生成IOS app专用密码教程
.如果没有APP账号的话,点此链接复制到浏览器打开appleid.apple官网,然后点击“创建您的APP ID” 。
|
数据安全/隐私保护 iOS开发
生成IOS app专用密码教程
生成IOS app专用密码教程
生成IOS app专用密码教程
|
数据安全/隐私保护 iOS开发
生成IOS app专用密码教程
生成IOS app专用密码教程
生成IOS app专用密码教程
WM
|
弹性计算 小程序 关系型数据库
基于ECS搭建的应用示例(博客、密码管理、同学地图、APP服务端等)详解之一
作为互联网行业从业者,头脑里总是会冒出各种各样的想法,当然可以用网络笔记、云盘甚至本地的方式等记录下自己的想法,然而如果想要落地尝试,则拥有一台自己的服务器就再好不过了。全栈开发已经讲了很久了,如果是前端,通过nodejs也可以搭建后端服务;如果是后端,通过flutter、uniapp等也可以搭建出各种端上的APP;如果非研发人员,通过低代码开发平台拖拽也可以。有了自己的产品之后,如果不满足于本地跑跑,那么就得面临选择应用的载体了,性价比最高的方式是选择云上ECS,下面拿我的几年使用经验来展开讲一下。
WM
413 0
基于ECS搭建的应用示例(博客、密码管理、同学地图、APP服务端等)详解之一
|
传感器 安全 生物认证
iOS传感器开发——为APP添加手机密码、指纹进行安全验证
iOS传感器开发——为APP添加手机密码、指纹进行安全验证
257 0
iOS传感器开发——为APP添加手机密码、指纹进行安全验证
|
前端开发 数据安全/隐私保护
app 记住密码功能,双Token
app记住密码功能的实现,解决用户在短时间不操作后重复登录的问题
5069 0