Jump to content
pduarte

Passar o token quando se requisita outras URL

Recommended Posts

pduarte

Bom dia, antes de mais quero dizer olá a todos e informar que sou novo por estas bandas. Encontro-me a estudar JAVA a cerca de um ano e meio, desenvolvi o backend de uma API e agora estou por minha "conta" a adapta-lo a uma WEB-API, e apesar das limitações estou a conseguir ultrapassar todas as dificuldades, à excepção de uma!

Então o que se passa é que na minha WEB-API , na qual uso o TOKEN para autenticação de usuario,tenho uma classe JWTAuthenticationFilter  que extende UsernamePasswordAuthenticationFilter. 

Até aqui tudo bem, usando o POSTMAN com esta classe gero o TOKEN atravez das credenciais de usuario , faço outra chamada, (por exemplo http://localhost:8080/usuarios/1) coloco o header "Authorization" manualmente e de seguinda o Bearer + Token e tudo funciona. Mas usando WEB-API com as views no browser normal, consigo na mesma gerar o header token usando jquery com AJAX, dá o 200OK, mas depois não consigo guardar o TOKEN e voltar a usa-lo no header Authorization nas outras requisiçoes. Peço a vossa ajuda, ja estou a um mês e ja tentei de tudo o que o que o meu pouco conhecimento me permitiu! Segue abaixo o codigo:

 

Classe JWTAuthenticationFilter
 

public class JWTAuthenticationFilter extends UsernamePasswordAuthenticationFilter {    
    protected AuthenticationManager authenticationManager;

    private JWTUtil jwtUtil;

    public JWTAuthenticationFilter(AuthenticationManager authenticationManager, JWTUtil jwtUtil) {
        this.authenticationManager = authenticationManager;
        this.jwtUtil = jwtUtil;
    }

    @Override 
    @Bean(name = BeanIds.AUTHENTICATION_MANAGER)
    public Authentication attemptAuthentication(HttpServletRequest req, 
                                                HttpServletResponse res) throws AuthenticationException{
        try {
        
        CredenciaisDTO creds = new ObjectMapper().readValue(req.getInputStream(), CredenciaisDTO.class);

        UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken(creds.getEmail(), creds.getSenha(), new ArrayList<>());
        
        Authentication auth = authenticationManager.authenticate(authToken);
        
        return auth;
        }
        
        catch(IOException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    protected void successfulAuthentication(HttpServletRequest req, HttpServletResponse res, FilterChain chain,
            Authentication auth) throws IOException, ServletException {
        
        String username = ((UserSS) auth.getPrincipal()).getUsername();
        String token = jwtUtil.generateToken(username);
        res.addHeader("Authorization", "Bearer" + token);
        res.addHeader("access-control-expose-headers", "Autorization");
    }
    
    public void filter(HttpServletRequest req, HttpServletResponse res, FilterChain chain,
            Authentication auth) throws IOException, ServletException  {
        String authorizationHeader = res.getHeader(HttpHeaders.AUTHORIZATION);    
        String token = authorizationHeader.substring("Bearer".length()).trim();
        res.setHeader("Authorization", "Bearer" + token);
        res.setHeader("access-control-expose-headers", "Autorization");
    }
    
    private class JWTAuthenticationFailureHandler implements AuthenticationFailureHandler{
        @Override
        public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception)
            throws IOException, ServletException{
            response.setStatus(401);
            response.setContentType("application/json");
            response.getWriter().append(json());
        }
        
        private String json() {
            long date = new Date().getTime();
            return "{\"timestamp\": "+ date + " ,"
                    + "status\": 401, "
                    + "\"error\": \"Não autorizado\", "
                    + "message\": \"Email ou senha inválidos\", "
                    + "\"path\": \"/login\"}";
        }
    }
}

Classe UsuarioResource:

@RestController
@RequestMapping(value="/usuarios")
public class UsuarioResource {
    
    @Autowired
    private UsuarioService service;
    
    @RequestMapping(value="/{id}", method=RequestMethod.GET)
    public ResponseEntity<Usuario> find(@PathVariable Integer id){
        Usuario obj = service.find(id);
        return ResponseEntity.ok().body(obj);
    }
    
    @RequestMapping(value="/email", method=RequestMethod.GET)
    public ResponseEntity<Usuario> find(@RequestParam(value="value") String email){
        Usuario obj = service.findByEmail(email);
        return ResponseEntity.ok().body(obj);
    }
    
    @RequestMapping(method=RequestMethod.POST)
    public ResponseEntity<Void> insert(@Valid @RequestBody UsuarioNewDTO objDto){
        Usuario obj = service.fromDTO(objDto);
        obj = service.insert(obj);
        URI uri = ServletUriComponentsBuilder.fromCurrentRequest()
                .path("/{id}").buildAndExpand(obj.getId()).toUri();
        return ResponseEntity.created(uri).build();
    }
    
    @RequestMapping(value="/{id}", method=RequestMethod.PUT)
    public ResponseEntity<Void> update(@Valid @RequestBody UsuarioDTO objDTO, @PathVariable Integer id){
        Usuario obj = service.fromDTO(objDTO);
        obj.setId(id);
        obj = service.update(obj);
        return ResponseEntity.noContent().build();
    }
    
    @PreAuthorize("hasAnyRole('ADMIN')")
    @RequestMapping(value="/{id}", method=RequestMethod.DELETE)
    public ResponseEntity<Void> delete(@PathVariable Integer id){
        service.delete(id);
        return ResponseEntity.noContent().build();
    }
    
    @PreAuthorize("hasAnyRole('ADMIN')")
    @RequestMapping(method=RequestMethod.GET)
    public ResponseEntity<List<UsuarioDTO>> findAll(){
        List<Usuario> list = service.findAll();
        List<UsuarioDTO> listDto = list.stream().map(obj -> new UsuarioDTO(obj)).collect(Collectors.toList());
        return ResponseEntity.ok().body(listDto);
    }
    
    @RequestMapping(value="/page",method=RequestMethod.GET)
    public ResponseEntity<Page<UsuarioDTO>> findPage(
            @RequestParam(value="page", defaultValue="0") Integer page,
            @RequestParam(value="linesPerPage", defaultValue="24") Integer linesPerPage,
            @RequestParam(value="orderBy", defaultValue="nome") String orderBy,
            @RequestParam(value="direction", defaultValue="ASC") String direction){
        Page<Usuario> list = service.findPage(page, linesPerPage, orderBy, direction);
        Page<UsuarioDTO> listDto = list.map(obj -> new UsuarioDTO(obj));
        return ResponseEntity.ok().body(listDto);
    }
    
    @RequestMapping(value = "/picture", method=RequestMethod.POST)
    public ResponseEntity<Void> uploadProfilePicure(@RequestParam(name="file")MultipartFile file){
        URI uri = service.uploadProfilePicture(file);  
        return ResponseEntity.created(uri).build();
    }
}

 


Pduarte

Share this post


Link to post
Share on other sites
HappyHippyHippo

O teu problema não é de Java, mas sim de Javascript. 

Se tens de guardar o token do lado do browser para o usar posteriormente, então será aí que terás de trabalhar. 

A solução mais simples é guardar-lo num cookie


IRC : sim, é algo que ainda existe >> #p@p

Share this post


Link to post
Share on other sites
pduarte

Obrigado HappyHippyHippo :).

Ja andei a "fuçar" e ja consegui perceber onde tenho de guardar o token e a maneira de o guardar, mas não consigo isola-lo numa variavel para o puxar para o "document.cookie". 

Eu para fazer o POST do user e da password uso o AJAX,que está a funcionar pois gera o tal header com o Bearer + Token como falei anteriormente. Mas agora nao o consigo puxar para o cookie.

O meu codigo do metodo POST no AJAX:

$(document).ready(
        function() {
      
            $("#loginForm").submit(function(event) {
                event.preventDefault();
                ajaxPost();
            });

            function ajaxPost() {

                // PREPARE FORM DATA
                var formData = {
                    email : $("#email").val(),
                    senha : $("#senha").val()
                }

                // DO POST
                $.ajax({
                    type : "POST",
                    contentType : "application/json",
                    url : "login",
                    data : JSON.stringify(formData),
                    dataType : 'text',
                    success : function(response) {

                        $("#postResultDiv").html("<strong>LOGADO</strong>"); // Aqui é so para ver se funcionou                 
                    },
                    error : function(e) {
                        alert("Crendeciais Invalidas")
                        console.log("ERROR ", e);
                    }

                }).then(function () {

                      document.cookie = "access_token=" + AAA;
                });
            }
        })

 

Eu não consigo descobrir o que colocar no meu AAA. Preciso de algo para puxar conteudo do header "Authorization" para guardar no document.cookie no lugar de AAA. 

 

PS: Não sei sedevoe continuar este topico aqui ou muda-lo para o javascript :s

Edited by pduarte
Forgot to write my code in correct way

Pduarte

Share this post


Link to post
Share on other sites
pduarte

Ja consegui, no meu caso resultou com:

 

$.ajax({
                type : "POST",
                contentType : "application/json",
                url : "login",
                data : JSON.stringify(formData),
                dataType : 'text',
                success :function(data, textStatus, request){
                    $("#postResultDiv").html("<strong>LOGADO</strong>");
                },

                error : function(e) {
                    alert("Credenciais Invalidas");
                    console.log("ERROR ", e);
                }
            }).then(function (data, textStatus, request) {

                document.cookie = "access_token=" + request.getResponseHeader('Authorization');
              //  document.location.replace("/login");
            });

Obrigado, essa dica do guardar no cookies foi absolutamente fundamental, pra que tem pouca experiencia, tinha de andar mais um mês a apanhar bonés lol :cheesygrin:


Pduarte

Share this post


Link to post
Share on other sites
pduarte

Já agora, para poder ajudar alguem com a mesma duvida que eu, depois criei uma função no documento JS para atribuir o nome ao cookie. Aqui fica em baixo: 

function getCookie(name) {
    var value = "; " + document.cookie;
    var parts = value.split("; " + name + "=");
    if (parts.length == 2) return parts.pop().split(";").shift();
}

depois é só chamar o cookie com o getCookie("access_token") e temos acesso a o nosso token guardado nos cookies :)


Pduarte

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.