final—前后端分离的网站

前后端分离的网站

  • 后台使用 express+mysql搭建
  • 前台使用vue-cli搭建

安装

        cnpm install express express-static cookie-parser body-parser multer cookie-session mysql consolidate --save

目录结构

  • libs:自定义的工具库
  • libs/db.js: 数据库操作
  • static:静态文件 css upload js
  • views: ejs模板目录
  • route: 路由
  • route/admin: 后台路由
  • route/api: 前台数据接口
  • app.js: 入口文件

设置静态文件目录,用于css、js等静态文件的获取

    app.use(express.static(path.join(__dirname, 'static')));


操作后信息提示功能

引入flash模块来实现页面通知功能(即成功与失败的信息显示)

  1. 什么是flash? 我们所说的flash即 connect-flash模块(https://github.com/jaredhanson/connect-flash),flash是一个在session中用于存储信息的特定区域。信息写入flash,下一次显示完毕后即被清除。典型的应用是结合重定向的功能,确保信息是提供给下一个被渲染的页面

  2. 安装模块

    npm install connect-flash --save
    
  3. 在app.js中添加调用此模块

    var flash = require('connect-flash');
    
    app.use(flash());//因为flash依赖session,所以他必须放在session后面
    
  4. 在res.locals中增加成功失败信息,以便所有模板中可以使用

    //用户登录数据分配
    app.use(function(req,res,next){
        //res.locals 属性是express模板引擎最后分配的数据对象,因为每个模板都要分配user数据,所以直接写入这个对象即可
        res.locals.user = req.session.user;
        res.locals.success = req.flash('success').toString();
        res.locals.error = req.flash('error').toString();
        next();
    });
    
  5. 设置flash中成功失败信息 /routes/users.js login

    router.post('/login', function (req, res, next) {
        var user = req.body;
        var username = user.username;
        var password = utils.md5(user.password);
        userModel.findOne({username: username, password: password}, function (err, doc) {
            if (err) {
                reg.flash('error','登录失败');
                res.redirect('back');
            } else {
                if (doc) {//登录成功后,将数据写入session
                    req.session.user = doc;
                    req.flash('success','登录成功');
                    res.redirect('/');
                } else {
                    req.flash('error','用户名或密码错误');
                    res.redirect('back');
                }
            }
        });
    });
    
  6. 模板中显示

    <% if(success){ %>
        <div class="alert alert-success"><%= success %></div>
    <% } %>
    <% if(error){ %>
        <div class="alert alert-danger"><%= error %></div>
    <% } %>
    
权限控制
  1. 根目录创建 middleware目录,并创建auth.js做权限控制

auth.js内容如下

    //登录后才能访问
    exports.checkLogin = function(req,res,next){
        if(req.session.user){
            next();
        }else{
            req.flash('error','请登录后查看');
            res.redirect('/users/login');
        }
    }
    //没登录时才能访问
    exports.checkNotLogin = function(req,res,next){
        if(req.session.user){
            req.flash('error','您已经登录了');
            res.redirect('/');
        }else{
            next();
        }
    }
  1. 在各个路由中根据需要引入对应的验证,如/routes/user.js

    var auth = require('../middleware/auth');//引入权限验证中间件
    
     router.get('/login',auth.checkNotLogin, function (req, res, next) {
         res.render('users/login', {title: '登录'});
     });
    
md5 加密
        const crypto = require('crypto');
        module.exports = {
            md5(str){
                return crypto.createHash('md5').update(str).digest('hex');
            }
        }
发表文章时可以上传图片

使用方法查看 Readme.md

  1. 安装multer中间件,处理图片上传
npm install multer --save
  1. 修改 /views/article/add.html 的form, 增加 enctype="multipart/form-data".增加 type=file表单

  2. 修改/model/models.js 中 artilce的骨架,增加 thumb 字段

  3. 创建目录uploads, /public/uploads

  4. 修改routes/article.js

    //引入multer处理上传图片
    var multer = require('multer');
    var storage = multer.diskStorage({
        //指定上传路径
        destination: function (req, file, cb) {
            //注意路径,位置不能写错,文件夹要存在,不然都会报错
            cb(null, 'public/uploads');
        },
        //指定上传文件名
        filename: function (req, file, cb) {
            cb(null, Date.now()+'.'+file.mimetype.slice(file.mimetype.indexOf('/')+1));
        }
    })
    
    var upload = multer({ storage: storage });
    
    router.post('/add',auth.checkLogin,upload.single('thumb'), function (req, res, next) {
        var article = req.body;
        article.user = req.session.user._id;
        //如果有上传文件,那么写入模型
        if(req.file){
            var uploadPath = '/uploads/'+req.file.filename;
            article.thumb = uploadPath;
        }
    
        new Model('articles')(article).save(function(err,doc){
            if(err){
                req.flash('error','添加文章失败');
                res.redirect('back');
            }else{
                if(doc){
                    req.flash('success','文章添加成功');
                    res.redirect('/');
                }
            }
        })
    
    });
    
可以将上传封装成中间件,创建 /middleware/multerUpload.js,将如下代码从article.js中移入,并修改如下。
    //引入multer处理上传图片
    var multer = require('multer');
    var storage = multer.diskStorage({
        //指定上传路径
        destination: function (req, file, cb) {
            //注意路径,位置不能写错,文件夹要存在,不然都会报错
            cb(null, 'public/uploads');
        },
        //指定上传文件名
        filename: function (req, file, cb) {
            cb(null, Date.now()+'.'+file.mimetype.slice(file.mimetype.indexOf('/')+1));
        }
    })

    module.exports = multer({ storage: storage });

在/routes/article.js中,引入。以后需要上传功能的地方,引入如下内容即可

    var upload = require('../middleware/multerUpload');//引入封装好的上传中间件

转载于:https://www.cnblogs.com/MrsQiu/p/7083554.html

好的,关于 Spring Boot JWT Token 的前后端分离问题,我可以为您提供一些帮助。 JWT(JSON Web Token)是一种基于 JSON 的开放标准(RFC 7519),用于在网络上安全传输声明。在前后端分离的应用中,通常会使用 JWT 来实现用户认证和授权。 下面是一个简单的示例,演示了如何在 Spring Boot 应用中使用 JWT 和前后端分离的方式进行用户认证。 首先,您需要在后端应用中添加 JWT 相关的依赖。可以使用以下 Maven 依赖: ```xml <dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt</artifactId> <version>0.9.1</version> </dependency> ``` 接下来,您需要编写一个 JWT 工具类,用于生成和验证 JWT。 ```java import io.jsonwebtoken.Claims; import io.jsonwebtoken.Jwts; import io.jsonwebtoken.SignatureAlgorithm; import io.jsonwebtoken.security.Keys; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import javax.crypto.SecretKey; import java.util.Date; import java.util.HashMap; import java.util.Map; @Component public class JwtUtils { @Value("${jwt.secret}") private String secret; @Value("${jwt.expiration}") private Long expiration; private static final String CLAIM_KEY_USERNAME = "sub"; private static final String CLAIM_KEY_CREATED = "iat"; private SecretKey generateKey() { return Keys.hmacShaKeyFor(secret.getBytes()); } public String generateToken(String username) { Map<String, Object> claims = new HashMap<>(); claims.put(CLAIM_KEY_USERNAME, username); claims.put(CLAIM_KEY_CREATED, new Date()); return Jwts.builder() .setClaims(claims) .setExpiration(new Date(System.currentTimeMillis() + expiration * 1000)) .signWith(generateKey(), SignatureAlgorithm.HS512) .compact(); } public Claims getClaimsFromToken(String token) { return Jwts.parserBuilder() .setSigningKey(generateKey()) .build() .parseClaimsJws(token) .getBody(); } public boolean isTokenExpired(String token) { Claims claims = getClaimsFromToken(token); Date expiration = claims.getExpiration(); return expiration.before(new Date()); } public boolean validateToken(String token, String username) { Claims claims = getClaimsFromToken(token); String subject = claims.getSubject(); Date expiration = claims.getExpiration(); return subject.equals(username) && !expiration.before(new Date()); } } ``` 在这个工具类中,我们使用了 io.jsonwebtoken 库来实现 JWT 的生成和验证。在生成 JWT 时,我们使用了一个密钥(secret)来签名 JWT。在验证 JWT 时,我们还检查了 JWT 中保存的用户名和过期时间是否正确。 接下来,您需要在 Spring Boot 应用中添加一个 JWT 认证过滤器,用于在请求到达后端之前验证 JWT。 ```java import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.web.filter.OncePerRequestFilter; import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; public class JwtAuthenticationFilter extends OncePerRequestFilter { @Autowired private JwtUtils jwtUtils; @Autowired private UserDetailsService userDetailsService; @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException { String header = request.getHeader("Authorization"); if (header != null && header.startsWith("Bearer ")) { String token = header.substring(7); String username = jwtUtils.getClaimsFromToken(token).getSubject(); if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) { UserDetails userDetails = userDetailsService.loadUserByUsername(username); if (jwtUtils.validateToken(token, username)) { UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities()); SecurityContextHolder.getContext().setAuthentication(authentication); } } } chain.doFilter(request, response); } } ``` 在这个过滤器中,我们从请求头中获取 JWT,然后使用之前编写的 JwtUtils 工具类来验证 JWT。如果 JWT 验证成功,则将用户信息添加到 Spring Security 的认证上下文中。 最后,在 Spring Boot 应用中添加一个登录接口,用于生成 JWT。 ```java import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.http.ResponseEntity; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.AuthenticationException; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.web.bind.annotation.*; import java.util.HashMap; import java.util.Map; @RestController @RequestMapping("/auth") public class AuthController { @Autowired private AuthenticationManager authenticationManager; @Autowired private JwtUtils jwtUtils; @Autowired private UserDetailsService userDetailsService; @PostMapping("/login") public ResponseEntity<?> login(@RequestBody LoginRequest loginRequest) throws AuthenticationException { authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(loginRequest.getUsername(), loginRequest.getPassword())); UserDetails userDetails = userDetailsService.loadUserByUsername(loginRequest.getUsername()); String token = jwtUtils.generateToken(userDetails.getUsername()); Map<String, Object> response = new HashMap<>(); response.put("token", token); return ResponseEntity.ok(response); } @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } } ``` 在这个登录接口中,我们首先使用 Spring Security 的 AuthenticationManager 来验证用户信息。如果验证成功,则使用 JwtUtils 工具类生成 JWT,并将 JWT 返回给前端应用。 以上就是一个简单的 Spring Boot JWT Token 的前后端分离示例。希望对您有所帮助!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值