I like the new template engine JTE and I am trying to learn this.
I know I can manually add the CSRF token as a request attribute and I have done it for my login form like so:
@GetMapping("/login")
public String login(Model model, CsrfToken token) {
model.addAttribute("csrf", token.getToken());
return "auth/login";
}
@param String title
@param String csrf
@template.main-layout(title = title, content = @`
<form action="/login" method="POST">
<div>
<input type="text" name="username" placeholder="Username: ">
</div>
<div>
<input type="password" name="password" placeholder="Username: ">
</div>
<div>
<input type="hidden" name="_csrf" value="${csrf}">
</div>
<div>
<input type="submit" value="Log in" />
</div>
</form>
`)
But in my main layout file in my dummy project, I want to have a condition that basically checks if the user is authenticated, if yes, i want to display a logout button, otherwise a login link.
Now, I don't want to pass a CSRF token as a @param for each view, this would be annoying,
Is there a good way to implement this directly in the template ?
Otherwise i am happy to learn how to contribute to open source and try build this, Or I might just need to learn thymeleaf because i think it has this functionality out of the box
The best way I have found so far is to use @ControllerAdvice
import org.springframework.security.web.csrf.CsrfToken;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ModelAttribute;
@ControllerAdvice
public class JteControllerAdvice {
@ModelAttribute
public void csrf(Model model, CsrfToken csrf) {
model.addAttribute("_csrf", csrf);
}
}
You can also use @ControllerAdvice to only target specific Controllers.