Implementando autenticação baseada em JWT em uma API RESTful JAX-RS \| TreinaWeb               Promoção no ar   Matricule-se agora e garanta **54% de desconto**  

  Termina em   Tempo restante da oferta: 07 Horas 

 07 Min 

 00 Seg 

   Tempo restante da oferta: 07 07 00 

  [Assinar →](https://www.treinaweb.com.br/checkout/pagamento/plano/anual?cupom=TW-SCLIENTE26) 

   [                ](https://www.treinaweb.com.br)  Explorar  

 [ Quanto custa? ](#assinatura) [ FAQ ](https://www.treinaweb.com.br#faq) [Matricule-se](#assinatura) [ Entrar ](https://www.treinaweb.com.br/login) 

     [ Início ](https://www.treinaweb.com.br) [ Artigos ](https://www.treinaweb.com.br/blog) Implementando autenticação baseada em JWT em uma API RESTful JAX-RS  [ Java ](https://www.treinaweb.com.br/blog/categoria/java) 

# Implementando autenticação baseada em JWT em uma API RESTful JAX-RS

 Segurança é um item essencial e uma forma de limitar o acesso da aplicação é através de autenticação, que uma API JAX-RS pode implementar através do JWT.

 [ Wladimilson M. Nascimento ](https://www.treinaweb.com.br/blog/autor/wladimilson-m-nascimento) 7 anos atrás

  ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2020/05/autenticação-jwt-em-api-jax-rs.png)  

Segurança deve ser um ponto vital para qualquer aplicação web. Não importando o tamanho ela sempre conterá dados que necessitam de alguma proteção. APIs também se enquadram neste quesito, mas as formas tradicionais de autenticação, baseadas em telas de login e sessão, não podem ser aplicadas neste tipo de aplicação.

Por serem stateless por definição, APIs RESTful procuram implementar autenticações baseadas em alguma informação nas solicitações do usuário. Sendo que as opções mais comuns são: **HTTP Basic Authentication**, onde o usuário e senha codificado em base64 é enviado no header **Authorization** da solicitação; e **Token Based Authentication**, onde é enviado no header **Authorization** da solicitação um token assinado, garantindo que ele não foi adulterado.

Devido a facilidade de implementação e a maior segurança, dessas duas opções, a opção mais utilizada é a **Token Based Authentication**, que utiliza o padrão aberto JSON Web Token (JWT). Baseado em JSON este padrão nos permite fornecer várias informações sobre o usuário de forma compacta e auto-contida.

Neste artigo veremos como implementar este tipo de autenticação em uma API RESTful JAX-RS.

[  ![Java - Fundamentos de JAX-WS e JAX-RS](https://d2knvm16wkt3ia.cloudfront.net/assets/svg-icon/java.svg)   Curso Java - Fundamentos de JAX-WS e JAX-RS Conhecer o curso ](https://www.treinaweb.com.br/curso/java-fundamentos-de-jax-ws-e-jax-rs)

## Gerando o Token de acesso da API

Para este artigo não criarei uma aplicação do zero, utilizarei como base a [API RESTful com a JAX-RS API que demostrei no meu artigo passado](https://www.treinaweb.com.br/blog/criando-uma-api-restful-com-a-jax-rs-api/).

Para gerar o token, utilizaremos a biblioteca [jjwt](https://github.com/jwtk/jjwt), assim, a primeira coisa a ser feita na aplicação é a adição das dependências dela:

```xml

    io.jsonwebtoken
    jjwt-api
    0.11.1

    io.jsonwebtoken
    jjwt-impl
    0.11.1
    runtime

    io.jsonwebtoken
    jjwt-jackson
    0.11.1
    runtime

```

Com as dependências adicionadas, criaremos uma nova entidade chamada `Usuario`:

```java
public class Usuario {
    private int idUsuario;
    private String usuario;
    private String senha;

    public int getIdUsuario() {
        return idUsuario;
    }

    public String getSenha() {
        return senha;
    }

    public void setSenha(String senha) {
        this.senha = senha;
    }

    public String getUsuario() {
        return usuario;
    }

    public void setUsuario(String usuario) {
        this.usuario = usuario;
    }

    public void setIdUsuario(int idUsuario) {
        this.idUsuario = idUsuario;
    }
}

```

E o recurso abaixo:

```java
@Path("/login")
public class LoginResource {
    private final SecretKey CHAVE = Keys.hmacShaKeyFor(
		"7f-j&CKk=coNzZc0y7_4obMP?#TfcYq%fcD0mDpenW2nc!lfGoZ|d?f&RNbDHUX6"
		.getBytes(StandardCharsets.UTF_8));

    @POST
    @Produces(MediaType.TEXT_PLAIN)
    @Consumes(MediaType.APPLICATION_JSON)
    public Response post(Usuario usuario)
    {
        try{
            if(
				usuario.getUsuario().equals("teste@treinaweb.com.br") 
					&& 
				usuario.getSenha().equals("1234")
			)
            {
                String jwtToken = Jwts.builder()
                    .setSubject(usuario.getUsuario())
                    .setIssuer("localhost:8080")
                    .setIssuedAt(new Date())
                    .setExpiration(
						Date.from(
							LocalDateTime.now().plusMinutes(15L)
								.atZone(ZoneId.systemDefault())
							.toInstant()))
                    .signWith(CHAVE, SignatureAlgorithm.RS512)
                    .compact();

                return Response.status(Response.Status.OK).entity(jwtToken).build();
            }
            else
                return Response.status(Response.Status.UNAUTHORIZED)
						.entity("Usuário e/ou senha inválidos").build();
        }
        catch(Exception ex)
        {
            return Response.status(
						Response.Status.INTERNAL_SERVER_ERROR
					).entity(ex.getMessage())
					.build();
        } 
    }
}

```

Note que nele há apenas um método, que realizará o login do usuário. Por esta ser uma aplicação simples, o usuário e senha válidos já estão definidos no código. Ao autenticar, será gerado um token:

```java
String jwtToken = Jwts.builder()
    .setSubject(usuario.getUsuario())
    .setIssuer("localhost:8080")
    .setIssuedAt(new Date())
    .setExpiration(
		Date.from(
			LocalDateTime.now().plusMinutes(15L)
				.atZone(ZoneId.systemDefault())
			.toInstant()))
    .signWith(CHAVE, SignatureAlgorithm.RS512)
    .compact();

```

Onde, é informado:

- Subject: o login do usuário;
- Issuer: quem está gerando o token;
- IssuedAt: data que o token foi gerado;
- Expiration: tempo de vida do token;
- sign: como o token será assinado;

Das informações, a mais importante é a assinatura do token. Neste exemplo ela utiliza uma chave textual visível:

```java
private final SecretKey CHAVE = Keys.hmacShaKeyFor(
	"7f-j&CKk=coNzZc0y7_4obMP?#TfcYq%fcD0mDpenW2nc!lfGoZ|d?f&RNbDHUX6"
	.getBytes(StandardCharsets.UTF_8));

```

Entretanto em uma aplicação real, esta chave precisa ser bem protegida, pois é através dela que os tokens serão validados pela aplicação. Assim, se uma pessoa mal-intencionada obter esta informação, ela poderá gerar tokens válidos e terá acesso aos recursos protegidos da API.

Ao testar o endpoint, se for informado o usuário e senha corretos, um token será gerado:

![Requisição de login correta, gerando um token](https://dkrn4sk0rn31v.cloudfront.net/uploads/2020/05/postman-post-login-token-gerado.png)

Caso contrário será retornado 401 Unauthorized:

![Requisição com a senha inválida, gerando uma resposta 401 Unauthorized](https://dkrn4sk0rn31v.cloudfront.net/uploads/2020/05/postman-post-login-invalido.png)

Com a geração do token pronta, temos que proteger nossos endpoints, o que veremos a seguir.

## Autenticando as solicitações

Como vimos acima, o token será enviado no header Authorization da solicitação. Assim, para autenticá-las é necessário analisar este header e verificar se o token informado é valido. Apenas nessas situações as solicitações devem ser permitidas.

Para fazer isso, podemos utilizar o `@NameBinding`, que é uma meta annotation que nos permite definir filtros e interceptadores no pipeline da solicitação. Estes filtros são implementados via anotação, assim, inicialmente uma anotação deve ser definida:

```java
@NameBinding
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE,ElementType.METHOD})
public @interface Authorize { }

```

Onde utilizamos o `@NameBinding` e indicamos que a anotação será aplicada em métodos.

É na implementação desta anotação que verificamos a validade do token:

```java
@Provider
@Authorize
@Priority(Priorities.AUTHENTICATION)
public class AuthorizeFilter implements ContainerRequestFilter {
    private final SecretKey CHAVE = 
            Keys.hmacShaKeyFor("7f-j&CKk=coNzZc0y7_4obMP?#TfcYq%fcD0mDpenW2nc!lfGoZ|d?f&RNbDHUX6"
                                .getBytes(StandardCharsets.UTF_8));

    @Override
    public void filter(ContainerRequestContext requestContext) throws IOException {
        String authorizationHeader = requestContext
										.getHeaderString(HttpHeaders.AUTHORIZATION);
        try {
            String token = authorizationHeader.substring("Bearer".length()).trim();

            Jwts.parserBuilder()
					.setSigningKey(CHAVE)
					.build()
					.parseClaimsJws(token);
        } catch (Exception e) {
            requestContext
				.abortWith(Response.status(Response.Status.UNAUTHORIZED)
				.build());
        }

    }

}

```

Inicialmente é indicado que a classe irá prover (`@Provider`) a implementação a nossa anotação (`@Authorize`) e que a prioridade dela no pipeline do JAX-RS é de autenticação (`AUTHENTICATION`). Ou seja, ela será executada antes dos endpoints.

Na classe, é obtido o token do header da solicitação:

```java
String authorizationHeader = requestContext.getHeaderString(HttpHeaders.AUTHORIZATION);
String token = authorizationHeader.substring("Bearer".length()).trim();

```

Em seguida é validado:

```java
Jwts.parserBuilder()
	.setSigningKey(CHAVE)
	.build()
	.parseClaimsJws(token);

```

O método `parseClaimsJws` obtém os dados presentes no token como: Subject, Issuer, etc; caso haja algo errado, é gerada uma exceção. Assim, caso ocorra qualquer erro é retornado que o usuário não tem permissão de acesso:

```java
requestContext.abortWith(Response.status(Response.Status.UNAUTHORIZED).build());

```

Com a anotação definida, ela pode ser aplicada aos endpoints:

```java
@Path("/pessoa")
public class PessoaResource {

    private PessoaRepository _repositorio = new PessoaRepository();

    @Authorize
    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public List get() {
        return _repositorio.GetAll();
    }

    @Authorize
    @GET
    @Path("{id}")
    @Produces(MediaType.APPLICATION_JSON)
    public Pessoa getById(@PathParam("id") int id) {
        return _repositorio.Get(id);
    }

    @Authorize
    @POST
    @Produces(MediaType.APPLICATION_JSON)
    @Consumes(MediaType.APPLICATION_JSON)
    public Response post(Pessoa pessoa)
    {
        try{
            _repositorio.Add(pessoa);
            return Response.status(Response.Status.CREATED).entity(pessoa).build();
        }
        catch(Exception ex)
        {
            return Response.status(
						Response.Status.INTERNAL_SERVER_ERROR
					).entity(ex.getMessage())
					.build();
        } 
    }

    @Authorize
    @PUT
    @Path("{id}")
    @Produces(MediaType.APPLICATION_JSON)
    @Consumes(MediaType.APPLICATION_JSON)
    public Response put(@PathParam("id") int id, Pessoa pessoa)
    {
        Pessoa p = _repositorio.Get(id);
        if(p == null)
            return Response.status(Response.Status.NOT_FOUND).build();

        try{
            pessoa.setId(id);
            _repositorio.Edit(pessoa);
            return Response.status(Response.Status.OK).entity(pessoa).build();
        }
        catch(Exception ex)
        {
            return Response.status(
						Response.Status.INTERNAL_SERVER_ERROR
					).entity(ex.getMessage())
					.build();
        } 
    }

    @Authorize
    @DELETE
    @Path("{id}")
    @Produces(MediaType.APPLICATION_JSON)
    public Response delete(@PathParam("id") int id)
    {
        Pessoa p = _repositorio.Get(id);
        if(p == null)
            return Response.status(Response.Status.NOT_FOUND).build();

        try{
            _repositorio.Delete(id);
            return Response.status(Response.Status.OK).build();
        }
        catch(Exception ex)
        {
            return Response.status(
						Response.Status.INTERNAL_SERVER_ERROR
					).entity(ex.getMessage())
					.build();
        } 
    }
}

```

Para testá-la vamos utilizar o Postman.

## Testando a autenticação

Inicialmente gere um token:

![Requisição de login gerando o token](https://dkrn4sk0rn31v.cloudfront.net/uploads/2020/05/postman-post-login-token-gerado_2.png)

Com o token gerado, ele deve ser informado na aba Auth do Postman:

![Aba Auth do Postman, informando o token](https://dkrn4sk0rn31v.cloudfront.net/uploads/2020/05/postman-aba-auth.png)

Não se esqueça de definir o tipo como Bearer Token. Com isso, ao enviar uma solicitação, ela será aceita:

![Requisição POST para pessoa, com token válido](https://dkrn4sk0rn31v.cloudfront.net/uploads/2020/05/postman-post-pessoa_autenticada.png)

Se o token não for informado, ou caso seja inválido, será retornado *401 Unauthorized*:

![Requisição POST para pessoa, com token inválido](https://dkrn4sk0rn31v.cloudfront.net/uploads/2020/05/postman-post-pessoa-sem-token.png)

[  ![Java - Fundamentos de JAX-WS e JAX-RS](https://d2knvm16wkt3ia.cloudfront.net/assets/svg-icon/java.svg)   Curso Java - Fundamentos de JAX-WS e JAX-RS Conhecer o curso ](https://www.treinaweb.com.br/curso/java-fundamentos-de-jax-ws-e-jax-rs)

## Conclusão

Neste artigo vimos uma implementação simples de autenticação utilizando o padrão JWT. Um padrão bem difundido e muito utilizado, então caso necessite implementar este tipo de autenticação na sua aplicação não deixe de dar uma olhada nele.

Mas independente do padrão utilizado, procure não deixar suas aplicações expostas, sempre adote um sistema de autenticação e conexão segura, HTTPS.

Por fim, você pode ver a aplicação demonstrada aqui no meu [Github](https://github.com/wladimilson/jax-rs-example).

- [ #Java ](https://www.treinaweb.com.br/blog/tag/java)
- [ #JAX-RS API ](https://www.treinaweb.com.br/blog/tag/jax-rs-api)
- [ #JWT ](https://www.treinaweb.com.br/blog/tag/jwt)

Autor

 ![Wladimilson M. Nascimento](//secure.gravatar.com/avatar/f0dd442f156a3eacd2880e9cd0eafbd1?d=mm)

## Wladimilson M. Nascimento

 Instrutor, nerd, cinéfilo e desenvolvedor nas horas vagas. Graduado em Ciências da Computação pela Universidade Metodista de São Paulo. 

 [Todos os artigos](https://www.treinaweb.com.br/blog/autor/wladimilson-m-nascimento)  

## Continue estudando

 Transforme leitura em prática com os cursos e formações da TreinaWeb.

 [Ver cursos](https://www.treinaweb.com.br/cursos)   

  Continue lendo

## Artigos relacionados

- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2021/07/fluxo-de-autenticacao-baseado-em-jwt-400x280.png)  [ Desenvolvimento ](https://www.treinaweb.com.br/blog/categoria/desenvolvimento) 

     5 anos atrás

    ##  [ Fluxo de autenticação baseado em JWT ](https://www.treinaweb.com.br/blog/fluxo-de-autenticacao-baseado-em-jwt) 

     Neste artigo iremos aprender de teórica como é o fluxo de autenticação baseado em JWT dentro de uma API REST.

     Ler artigo
- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2022/12/NEST-JS-400x280.png)  [ Desenvolvimento Back-end ](https://www.treinaweb.com.br/blog/categoria/desenvolvimento-back-end) 

     4 anos atrás

    ##  [ Autenticação: Refresh Token com NestJS ](https://www.treinaweb.com.br/blog/autenticacao-refresh-token-com-nestjs) 

     Neste artigo vamos continuar no assunto de autenticação, abordando a estratégia de refresh token com o NestJS.

     Ler artigo
- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2021/08/NEST-JS-400x280.png)  [ Desenvolvimento Back-end ](https://www.treinaweb.com.br/blog/categoria/desenvolvimento-back-end) 

     4 anos atrás

    ##  [ Autenticação: Geração de Token JWT com NestJS e Passport ](https://www.treinaweb.com.br/blog/autenticacao-geracao-de-token-jwt-com-nestjs-e-passport) 

     Neste artigo vamos criar uma aplicação para a geração de Tokens JWT utilizando NestJS e a biblioteca Passport.

     Ler artigo
- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2019/04/16095041/OCELOT-400x280.png)  [ C# ](https://www.treinaweb.com.br/blog/categoria/csharp) 

     8 anos atrás

    ##  [ Criando um API Gateway com ASP.NET Core e Ocelot ](https://www.treinaweb.com.br/blog/criando-um-api-gateway-com-asp-net-core-e-ocelot) 

     Conheça o conceito de API Gateway e veja como criá-lo em uma aplicação ASP.NET utilizando a biblioteca Ocelot.

     Ler artigo
- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2017/06/seguranca-em-soa-como-proteger-os-web-services-400x280.png)  [ Segurança da Informação ](https://www.treinaweb.com.br/blog/categoria/seguranca-da-informacao) 

     10 anos atrás

    ##  [ Segurança em SOA: Como proteger os web services? ](https://www.treinaweb.com.br/blog/seguranca-em-soa-como-proteger-os-web-services) 

     Você sabe realmente como deve funcionar e como proteger um serviço SOA? Veremos nesse artigo como proteger web services que utilizem a arquitetura SOA.

     Ler artigo
- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2020/09/o_que_e_firebase-400x280.png)  [ Javascript ](https://www.treinaweb.com.br/blog/categoria/javascript) 

     6 anos atrás

    ##  [ O que é Firebase? ](https://www.treinaweb.com.br/blog/o-que-e-firebase) 

     Veja neste artigo o que é Firebase.

     Ler artigo
- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2021/05/spring-framework-400x280.png)  [ Java ](https://www.treinaweb.com.br/blog/categoria/java) 

     6 anos atrás

    ##  [ O que é Spring Framework? ](https://www.treinaweb.com.br/blog/o-que-e-spring-framework) 

     Confira neste artigo o Spring framework: um ecossistema de desenvolvimento para facilitar a criação de aplicações Java.

     Ler artigo
- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2019/06/25105828/DJANGO-AUTENTICAÇÃO-2-400x280.png)  [ Python ](https://www.treinaweb.com.br/blog/categoria/python) 

     8 anos atrás

    ##  [ Implementando autenticação no Django – Parte 2 ](https://www.treinaweb.com.br/blog/implementando-autenticacao-no-django-parte-2) 

     Veja neste artigo como implementar os recursos de logout, alteração de senha e proteção de páginas em projetos Django.

     Ler artigo
- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2019/06/21114028/DJANGO-AUTENTICAÇÃO-1-400x280.png)  [ Python ](https://www.treinaweb.com.br/blog/categoria/python) 

     8 anos atrás

    ##  [ Implementando autenticação no Django - Parte 1 ](https://www.treinaweb.com.br/blog/implementando-autenticacao-no-django-parte-1) 

     A autenticação é uma das principais funcionalidades em um sistema. É com ela que protegemos as funcionalidades de uma aplicação e permitimos que estas só sejam acessadas por usuários cadastrados e autenticados previamente. Nesta série de artigos, veremos como implementar os principais recursos do módulo de autenticação do Django.

     Ler artigo
- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2021/04/o-que-e-o-spring-security-400x280.png)  [ Java ](https://www.treinaweb.com.br/blog/categoria/java) 

     6 anos atrás

    ##  [ O que é o Spring Security? ](https://www.treinaweb.com.br/blog/o-que-e-o-spring-security) 

     Neste artigo veremos o que é o Spring Security, quais suas funcionalidades e como ele pode aumentar a segurança de nossas aplicações Java.

     Ler artigo
- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2023/05/NEST-JS-UPLOAD-ARQUIVOS-400x280.png)  [ Desenvolvimento Back-end ](https://www.treinaweb.com.br/blog/categoria/desenvolvimento-back-end) 

     3 anos atrás

    ##  [ Guia do framework NestJS ](https://www.treinaweb.com.br/blog/guia-do-framework-nestjs) 

     Neste guia do framework NestJS vamos fazer um compilado de tópicos úteis sobre o framework, desde criar um projeto básico até autenticação.

     Ler artigo
- ![](https://dkrn4sk0rn31v.cloudfront.net/uploads/2020/07/aplicando-hateoas-em-uma-api-jax-rs-400x280.png)  [ Java ](https://www.treinaweb.com.br/blog/categoria/java) 

     6 anos atrás

    ##  [ Aplicando HATEOAS em uma API JAX-RS ](https://www.treinaweb.com.br/blog/aplicando-hateoas-em-uma-api-jax-rs) 

     Veja como implementar o HATEOAS em uma aplicação JAX-RS-Jersey de forma simples com os recursos fornecidos por esta especificação.

     Ler artigo

## Um ano de acesso total para você viver de programação.

 Todos os cursos e formações da TreinaWeb numa única assinatura, com professores que atuam no mercado, suporte direto e certificados. Do primeiro `console.log` ao mercado de trabalho.

- **1 ano** de acesso a **todos os cursos**
- Cursos novos **toda semana**
- Suporte **direto com professores**
- Plano de carreira **personalizado**
- **Certificados digitais** inclusos
- **Aplicativos** para Android e iOS, com **acesso offline**

    **Garantia incondicional de satisfação** 

 Teste por 7 dias e, se não fizer sentido para você, devolvemos seu dinheiro.

### Acesso completo a todos os cursos e dezenas de Formações.

 12 meses 

  Economize R$ 840,00  54% OFF 

 de 12x R$ 129,00 por apenas

 12x  R$ 59,00

 sem juros no cartão de crédito ou R$ 599,00 à vista

  Oferta termina em  **07h 07min 00s**

- Acesso imediato e ilimitado durante 1 ano.
- Plano de carreira personalizado.
- Suporte direto com professores.
- E muito mais!

 [Matricule-se agora](https://www.treinaweb.com.br/checkout/pagamento/plano/anual?cupom=TW-SCLIENTE26)

     [                ](https://www.treinaweb.com.br)

 Escola online de programação, tecnologia e IA.

- [  ](https://www.facebook.com/TreinaWeb/)
- [  ](https://www.instagram.com/treinaweb/)
- [  ](https://www.youtube.com/user/TreinaWeb)
- [  ](https://twitter.com/treinaweb)
- [  ](https://www.linkedin.com/company/treinaweb)
- [  ](https://github.com/treinaweb)

## Inscreva-se em nossa newsletter

Receba lançamentos, promoções e novidades.

   Seu nome     Seu WhatsApp     Seu melhor e-mail   Inscrever-se 

## Cursos

- [ Base para Devs ](https://www.treinaweb.com.br/categoria/base-para-devs)
- [ Front-end ](https://www.treinaweb.com.br/categoria/desenvolvimento-front-end)
- [ Back-end ](https://www.treinaweb.com.br/categoria/desenvolvimento-back-end)
- [ Mobile ](https://www.treinaweb.com.br/categoria/desenvolvimento-mobile)
- [ Bancos de Dados ](https://www.treinaweb.com.br/categoria/bancos-de-dados)
- [ Cloud ](https://www.treinaweb.com.br/categoria/cloud-computing)
- [ IA ](https://www.treinaweb.com.br/categoria/ia)
- [ E mais ](https://www.treinaweb.com.br/categoria/e-mais)
- [ Ver todos os cursos ](https://www.treinaweb.com.br/cursos)

## Conteúdo

- [ Formações ](https://www.treinaweb.com.br/formacoes)
- [ Projetos práticos ](https://www.treinaweb.com.br/projetos-praticos)
- [ Direto ao ponto ](https://www.treinaweb.com.br/direto-ao-ponto)
- [ Planos ](https://www.treinaweb.com.br#assinatura)
- [ Depoimentos ](https://www.treinaweb.com.br#depoimentos)
- [ Comunidade ](https://www.treinaweb.com.br#comunidade)
- [ Corpo docente ](https://www.treinaweb.com.br#docente)

## A empresa

- [ Sobre a TreinaWeb ](https://www.treinaweb.com.br#sobre)
- [ Perguntas frequentes ](https://www.treinaweb.com.br#faq)
- [ Vantagens de estudar na TreinaWeb ](https://www.treinaweb.com.br/vantagens-de-estudar-na-treinaweb)
- [ Cursos para empresas ](https://www.treinaweb.com.br/empresas)
- [ Sugira um novo curso ](https://www.treinaweb.com.br/sugerir-curso)
- [ Trabalhe conosco ](https://www.treinaweb.com.br/trabalhe-conosco)
- [ Artigos ](https://www.treinaweb.com.br/blog)
- [ Desenvolvedores e agentes ](https://www.treinaweb.com.br/developers)
- [ Contato ](https://www.treinaweb.com.br/contato)
- [ Política de privacidade ](https://www.treinaweb.com.br/politica-de-privacidade)
- [ Termos de uso ](https://www.treinaweb.com.br/termos-de-uso)

## Baixe nosso aplicativo

 [   Disponível na **App Store**  ](https://apps.apple.com/us/app/treinaweb/id1322729447) [   Disponível no **Google Play**  ](https://play.google.com/store/apps/details?id=br.com.treinaweb.mobile) 

  Av. Paulista, 1765, Conj 71 e 72 · Bela Vista · São Paulo · SP · 01311-200   © 2004 – 2026 TreinaWeb Tecnologia LTDA · CNPJ 06.156.637/0001-58
