客服热线:139 1319 1678

融合门户

融合门户在线试用
融合门户
在线试用
融合门户解决方案
融合门户
解决方案下载
融合门户源码
融合门户
源码授权
融合门户报价
融合门户
产品报价

26-5-25 13:43

张伟(开发者):李娜,我们最近在做融合服务门户的开发,需要把招标文件的功能也整合进去。你对登录模块有什么建议吗?

李娜(架构师):张伟,首先得确定用户身份验证的方式。比如,是使用传统的用户名密码,还是OAuth、JWT等现代方式?这会影响后续的接口设计和安全性。

张伟:目前公司内部系统用的是基于Token的认证,可能更适合我们现在的架构。不过,招标文件可能需要更严格的权限控制。

李娜:没错,我们可以考虑引入RBAC(基于角色的访问控制)。这样不同的用户角色可以访问不同级别的招标文件。比如,普通用户只能查看公开的招标信息,而管理员可以编辑或下载完整文件。

张伟:那登录流程应该怎么设计呢?我之前做过一个简单的登录页面,但没考虑到多系统集成的问题。

李娜:登录应该是一个独立的服务模块,最好是微服务架构中的一个子系统。这样其他模块如招标文件系统就可以通过API调用登录服务来验证用户身份。

张伟:明白了,那具体怎么实现呢?有没有示例代码可以参考?

李娜:当然有。下面是一个简单的登录接口示例,使用Spring Boot框架,结合JWT实现身份验证。


// LoginController.java
@RestController
@RequestMapping("/api/auth")
public class AuthController {

    @Autowired
    private UserService userService;

    @PostMapping("/login")
    public ResponseEntity login(@RequestBody LoginRequest request) {
        User user = userService.findByUsername(request.getUsername());
        if (user == null || !user.getPassword().equals(request.getPassword())) {
            return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("Invalid credentials");
        }

        String token = JwtUtil.generateToken(user.getUsername());
        return ResponseEntity.ok(new AuthResponse(token));
    }
}
    

张伟:这个代码看起来不错,但我还想看看前端是怎么处理登录的。

李娜:前端可以用Axios发送POST请求到登录接口,获取返回的token,并将其存储在localStorage或者sessionStorage中。之后每次请求都需要带上这个token作为Authorization头。

张伟:明白了,那在访问招标文件的时候,怎么确保用户已经登录了呢?

李娜:我们需要在每个需要鉴权的接口上添加拦截器。比如,在Spring中可以使用Filter或者AOP来检查请求头中的token是否有效。

张伟:那具体的拦截逻辑怎么写呢?能给我一个例子吗?

李娜:好的,下面是一个简单的JWT拦截器示例。


// JwtInterceptor.java
@Component
public class JwtInterceptor implements HandlerInterceptor {

    @Autowired
    private JwtUtil jwtUtil;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String token = request.getHeader("Authorization");
        if (token != null && token.startsWith("Bearer ")) {
            token = token.substring(7);
            if (jwtUtil.validateToken(token)) {
                String username = jwtUtil.getUsernameFromToken(token);
                request.setAttribute("username", username);
                return true;
            }
        }
        response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized");
        return false;
    }
}
    

张伟:这个拦截器很实用,那在招标文件的控制器里,怎么根据用户角色来限制访问呢?

李娜:可以使用Spring Security的注解,比如@PreAuthorize,根据用户角色来决定是否允许访问某个方法。

张伟:比如,如果用户是“admin”,可以访问所有文件;如果是“viewer”,只能查看公开的文件。

李娜:对,下面是一个示例。


// BidFileController.java
@RestController
@RequestMapping("/api/bidfiles")
public class BidFileController {

    @GetMapping("/{id}")
    @PreAuthorize("hasRole('USER') or hasRole('ADMIN')")
    public ResponseEntity getBidFile(@PathVariable Long id) {
        BidFile file = bidFileService.findById(id);
        return ResponseEntity.ok(file);
    }

    @PostMapping
    @PreAuthorize("hasRole('ADMIN')")
    public ResponseEntity createBidFile(@RequestBody BidFile file) {
        BidFile saved = bidFileService.save(file);
        return ResponseEntity.ok(saved);
    }
}
    

张伟:这样就能实现权限控制了。不过,如果用户没有登录,直接访问招标文件页面会怎么样?

李娜:这时候拦截器就会阻止请求,返回401错误。前端可以根据这个错误跳转到登录页面,或者提示用户未登录。

张伟:明白了。那登录系统的安全性方面需要注意什么?

李娜:首先,密码不能明文传输,必须加密。其次,JWT的签名要足够强,避免被篡改。另外,token的有效期也要合理设置,防止长期有效带来的安全风险。

张伟:那是不是还需要考虑跨域问题?比如,前端和后端部署在不同的域名下?

李娜:是的,跨域请求需要配置CORS。在Spring Boot中,可以通过添加@EnableWebMvc和配置WebMvcConfigurer来解决这个问题。

张伟:有没有示例代码?

李娜:有的,下面是配置CORS的代码。


@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/api/**")
                .allowedOrigins("http://localhost:3000")
                .allowedMethods("GET", "POST", "PUT", "DELETE")
                .allowedHeaders("Content-Type", "Authorization");
    }
}
    

张伟:看来我们的登录系统已经初步成型了。接下来是不是要考虑测试和部署?

李娜:是的,测试是关键。可以使用JUnit进行单元测试,Postman测试API。部署的话,可以考虑Docker容器化,方便管理和扩展。

融合服务门户

张伟:好的,谢谢你的指导!

李娜:不客气,有问题随时找我!

智慧校园一站式解决方案

产品报价   解决方案下载   视频教学系列   操作手册、安装部署  

  微信扫码,联系客服