成功登录后,Spring Boot Thymeleaf实现文件下载功能
P粉957661544
P粉957661544 2024-03-28 09:54:29
0
1
351

我想提供一个带有 Spring Boot 的 Web 服务,它能够从 MySQL 数据库下载转储。

但下载不应该适合所有人。所以我需要一种登录。不太确定凭据将存储在哪里,有可能它们只是硬编码在应用程序本身中。

我有点迷失,不知道如何实现。

这是我到目前为止得到的:

@Controller
public class EBMysqldumpController {

    private EBMysqldumpService mysqldumpService;

    @Autowired
    public EBMysqldumpController(EBMysqldumpService mysqldumpService) {
        this.mysqldumpService = mysqldumpService;
    }

    @GetMapping("/login")
    public String showLoginForm(Model model) {
        model.addAttribute("userDto", new UserDto());
        return "mysqldump-login";
    }

    @PostMapping(path = "/login")
    public String validateLoginForm(@Valid UserDto userDto, BindingResult result, HttpServletRequest request) {
        if (result.hasErrors()) {
            return "mysqldump-login";
        }

        if (!this.mysqldumpService.checkLogin(userDto)) {
            result.addError(new ObjectError("", "Wrong username and/or password"));
            return "mysqldump-login";
        }

        return "redirect:/file";
    }

    @PostMapping(path = "/file")
    public ResponseEntity<Resource> startMysqlDump(@Valid UserDto userDto, Model model) throws IOException, InterruptedException, MysqldumpException {
        if (!this.mysqldumpService.checkLogin(userDto)) {
            return new ResponseEntity<>(HttpStatus.UNAUTHORIZED);
        }

        File mysqlDump = this.mysqldumpService.getMysqlDumpFile();
        ByteArrayResource byteArrayResource = this.mysqldumpService.getByteArrayResourceFromFile(mysqlDump);

        HttpHeaders headers = getMysqldumpHeaders(mysqlDump.getName());
        ResponseEntity<Resource> body = ResponseEntity.ok()
                .headers(headers)
                .contentLength(mysqlDump.length())
                .contentType(MediaType.APPLICATION_OCTET_STREAM)
                .body(byteArrayResource);

        this.mysqldumpService.deleteFile(mysqlDump);

        return body;
    }

    private HttpHeaders getMysqldumpHeaders(String filename) {
        ContentDisposition contentDisposition = ContentDisposition.inline().filename(filename).build();

        HttpHeaders headers = new HttpHeaders();
        headers.setContentDisposition(contentDisposition);

        return headers;
    }

}

目前控制器在“/login”处显示登录页面。提交表单后,控制器检查凭据是否正确,如果不正确,则会再次显示带有错误消息的登录页面。

但我的问题是,登录成功后我不知道该做什么。当我直接调用它时,下载工作正常,但使用重定向时它不起作用,因为我发出了一个发布请求以确保刚刚登录的用户可以下载该文件。如果我发出获取请求,每个人都可以使用该链接。

我有一种感觉,我处理问题的方式是错误的。你会推荐什么?登录成功后如何开始下载?

P粉957661544
P粉957661544

全部回复(1)
P粉574695215

我建议将 Spring Security 添加到您的项目中,并在其中有一个硬编码的用户:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

@Configuration
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.inMemoryAuthentication()
                .passwordEncoder(passwordEncoder)
            .withUser("user1").password("my-secret-pwd").roles("USER");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests(
                    registry -> registry.mvcMatchers("/**").authenticated()
            )
            .formLogin();
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return NoOpPasswordEncoder.getInstance();
    }
}
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板