English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Connexion et déconnexion Spring Angular

Dans cette section, nous allons créer une application Web de connexion et de déconnexion. L'application comprend des formulaires d'inscription et de connexion. Dans cette intégration, nous utilisons Spring pour la partie back-end, et Angular pour la partie front-end.

Application de travail

Une fois l'application déployée sur le serveur, une page d'accueil est générée contenant deux liens-Inscription et connexion.Les nouveaux utilisateurs peuvent choisir de s'inscrire et de s'inscrire en remplissant les détails nécessaires.Mais, les utilisateurs existants peuvent se connecter avec leur ID e-mail et leur mot de passe.Après la connexion, nous pouvons obtenir les détails des utilisateurs existants.Enfin, nous pouvons nous déconnecter en cliquant sur le lien de déconnexion.

Outils à utiliser

Utilisez tout IDE pour développer des projets Spring et Hibernate. Cela peut être MyEclipse/Eclipse/Netbeans。Ici, nous utilisons Eclipse。Pour la base de données, MySQL.Utilisez tout IDE pour développer un projet Angular. Cela peut être Visual Studio Code/Sublime。Ici, nous utilisons Visual Studio Code。Serveur: Apache Tomcat/JBoss/Glassfish/Weblogic/Websphere。

Les technologies que nous utilisons

Ici, nous utilisons les technologies suivantes:

Spring5 Hibernate5 Angular6 MYSQL

Créer la base de données

Créons la base de données loginlogoutexample 。Aucun besoin de créer de table, car Hibernate le créera automatiquement。

Module Spring

Voyons la structure de répertoires Spring que nous devons suivre:

Pour développer une application de connexion et de déconnexion, suivez les étapes suivantes: -

Ajouter les dépendances au fichier pom.xml.

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.w3codebox</groupId>
  <artifactId>LoginLogoutExample/artifactId>
  <packaging>war</packaging>
  <version>0.0.1-SNAPSHOT</version>
  <name>LoginLogoutExample Maven Webapp/name>
  <url>http://maven.apache.org/url>
  
  
  	<properties>
		<springframework.version>5.0.6.RELEASE</springframework.version>
		<hibernate.version>5.2.16.Final</hibernate.version>
		<mysql.connector.version>5.1.45</mysql.connector.version>
		<c3po.version>0.9.5.2</c3po.version>
		<maven.compiler.source>1.8</maven.compiler.source>
		<maven.compiler.target>1.8</maven.compiler.target>
	</properties>
  
  
  <dependencies>
  
  <!-- Spring -->
	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-webmvc</artifactId>
		<version>${springframework.version}</version>
	</dependency>
	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-tx</artifactId>
		<version>${springframework.version}</version>
	</dependency>
	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-orm</artifactId>
		<version>${springframework.version}</version>
	</dependency>
	<!-- Ajouter Jackson pour les convertisseurs JSON -->
	<dependency>
		<groupId>com.fasterxml.jackson.core</groupId>
		<artifactId>jackson-databind</artifactId>
		<version>2.9.5</version>
	</dependency>
	<!-- Hibernate -->
	<dependency>
		<groupId>org.hibernate</groupId>
		<artifactId>hibernate-core</artifactId>
		<version>${hibernate.version}</version>
	</dependency>
	<!-- MySQL -->
	<dependency>
		<groupId>mysql</groupId>
		<artifactId>mysql-connector-java/artifactId>
		<version>${mysql.connector.version}</version>
	</dependency>
	<!-- C3PO -->
	<dependency>
		<groupId>com.mchange</groupId>
		<artifactId>c3p0</artifactId>
		<version>${c3po.version}</version>
	</dependency>
	<!-- Servlet+JSP+JSTL -->
	<dependency>
		<groupId>javax.servlet</groupId>
		<artifactId>javax.servlet-api/artifactId>
		<version>3.1.0</version>
	</dependency>
	<dependency>
		<groupId>javax.servlet.jsp</groupId>
		<artifactId>javax.servlet.jsp-api/artifactId>
		<version>2.3.1</version>
	</dependency>
	<dependency>
		<groupId>javax.servlet</groupId>
		<artifactId>jstl/artifactId>
		<version>1.2</version>
	</dependency>
	<!-- pour compenser java 9 ne pas inclure jaxb -->
	<dependency>
		<groupId>javax.xml.bind</groupId>
		<artifactId>jaxb-api/artifactId>
		<version>2.3.0</version>
	</dependency>
	<!--  Dépendance de jeton Web -->
    <dependency>
    	<groupId>io.jsonwebtoken</groupId>
    	<artifactId>jjwt</artifactId>
    	<version>0.9.1</version>
	</dependency>
	 	
 	<!--  Dépendance JUnit -->
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>3.8.1</version>
        <scope>test</scope>
    </dependency>
    
	<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-dbcp2 -->
	<dependency>
	    <groupId>org.apache.commons</groupId>
	    <artifactId>commons-dbcp2</artifactId>
	    <version>2.0</version>
	</dependency> 
  </dependencies>
  
  
  <build>
    <finalName>LoginLogoutExample</finalName>
  </build>
</project>

Création de la classe de configuration
Nous exécutons une configuration basée sur les annotations plutôt que XML. Par conséquent, nous créons deux classes et y spécifions la configuration requise.

DemoAppConfig.java

package com.w;3codebox.LoginLogoutExample.config;
import java.beans.PropertyVetoException;
import java.util.Properties;
import javax.sql.DataSource;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.orm.hibernate5.HibernateTransactionManager;
import org.springframework.orm.hibernate5.LocalSessionFactoryBean;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import com.mchange.v2.c3p0.ComboPooledDataSource;
@Configuration
@EnableWebMvc
@EnableTransactionManagement
@ComponentScan("com.w3codebox.LoginLogoutExample})
@PropertySource(value = { "classpath:persistence-mysql.properties" })
@PropertySource(value = { "classpath:persistence-mysql.properties" })
@PropertySource(value = { "classpath:application.properties" })
public class DemoAppConfig implements WebMvcConfigurer {
	@Autowired
	private Environment env;
	@Bean
	public DataSource myDataSource() {
		// create connection pool
		ComboPooledDataSource myDataSource = new ComboPooledDataSource();
		// set the jdbc driver
		try {
			myDataSource.setDriverClass("com.mysql.jdbc.Driver");		
		}
		catch (PropertyVetoException exc) {
			throw new RuntimeException(exc);
		}
		// set database connection props
		myDataSource.setJdbcUrl(env.getProperty("jdbc.url"));
		myDataSource.setUser(env.getProperty("jdbc.user"));
		myDataSource.setPassword(env.getProperty("jdbc.password"));
		// set connection pool props
		myDataSource.setInitialPoolSize(getIntProperty("connection.pool.initialPoolSize"));
		myDataSource.setMinPoolSize(getIntProperty("connection.pool.minPoolSize"));
		myDataSource.setMaxPoolSize(getIntProperty("connection.pool.maxPoolSize"));		
		myDataSource.setMaxIdleTime(getIntProperty("connection.pool.maxIdleTime"));
		return myDataSource;
	}
	private Properties getHibernateProperties() {
		// set hibernate properties
		Properties props = new Properties();
		props.setProperty("hibernate.dialect", env.getProperty("hibernate.dialect"));
		props.setProperty("hibernate.show_sql", env.getProperty("hibernate.show_sql"));
		props.setProperty("hibernate.format_sql", env.getProperty("hibernate.format_sql"));
		props.setProperty("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl"));
		retourner props;				
	}
	// Besoin d'une méthode d'aide 
		// Lire la propriété d'environnement et la convertir en int
		private int getIntProperty(String propName) {
			String propVal = env.getProperty(propName);
			// Maintenant convertir en int
			int intPropVal = Integer.parseInt(propVal);
			retourner intPropVal;
		}
		@Bean
		public LocalSessionFactoryBean sessionFactory(){
			// Créer une session factory
			LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
			// Définir les propriétés
			sessionFactory.setDataSource(myDataSource());
			sessionFactory.setPackagesToScan(env.getProperty("hibernate.packagesToScan"));
			sessionFactory.setHibernateProperties(getHibernateProperties());
			return sessionFactory;
		}
		@Bean
		@Autowired
		public HibernateTransactionManager transactionManager(SessionFactory sessionFactory) {
			// Configurer le gestionnaire de transactions basé sur l'usine de session
			HibernateTransactionManager txManager = new HibernateTransactionManager();
			txManager.setSessionFactory(sessionFactory);
			return txManager;
		}	
}

MySpringMvcDispatcherServletInitializer.java

package com.w;3codebox.LoginLogoutExample.config;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
public class MySpringMvcDispatcherServletInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
	@Override
	protected Class<?>[] getRootConfigClasses() {
		// TOdo Auto-métode d'esquisse généré
		return null;
	}
	@Override
	protected Class<?>[] getServletConfigClasses() {
		return new Class[] { DemoAppConfig.class };
	}
	@Override
	protected String[] getServletMappings() {
		return new String[] { "/" };
	}
}

Créer une classe d'entité
Ici, nous allons créer les classes d'entités suivantes: AdminDetail.java-C'est une Entity/Classe POJO (ancien objet Java ordinaire). Token.java-Pour l'authentification.

AdminDetail.java

package com.w;3codebox.LoginLogoutExample.entity;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(nom="admin_detail")
public class AdminDetail {
	@Id
	@GeneratedValue(strategy=GenerationType.AUTO)
	@Column(nom="admin_id")
	private int adminID;
	@Column(nom="email_id", unique=true)
	public String emailId;
	@Column(nom="nom")
	public String nom;
	@Column(nom="mot de passe")
	public String mot de passe;
	@Column(nom="rôle")
	public String rôle;
	public AdminDetail() { }
	public AdminDetail(int adminID, String emailId, String nom, String mot de passe, String rôle) {
		super();
		this.adminID = adminID;
		this.emailId = emailId;
		this.nom = nom;
		this.mot de passe = mot de passe;
		this.rôle = rôle;
	}
	public int getAdminID() {
		retourner adminID;
	}
	public void setAdminID(int adminID) {
		this.adminID = adminID;
	}
	public String getEmailId() {
		return emailId;
	}
	public void setEmailId(String emailId) {
		this.emailId = emailId;
	}
	public String getNom() {
		retourner nom;
	}
	public void setNom(String nom) {
		this.nom = nom;
	}
	public String getMotDePasse() {
		retourner mot de passe;
	}
	public void setMotDePasse(String mot de passe) {
		this.mot de passe = mot de passe;
	}
	public String getRôle() {
		retourner rôle;
	}
	public void setRôle(String rôle) {
		this.rôle = rôle;
	}
	@Override
	public String toString() {
		retourner "AdminDetail [adminID=" + adminID + ", emailId=" + emailId + ", nom=" + nom + ", mot de passe=" + mot de passe
				+ ", rôle=" + rôle + "]";
	}
}

Token.java

package com.w;3codebox.LoginLogoutExample.entity;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name="Token")
public class Token {
	@Id
	@GeneratedValue(strategy=GenerationType.AUTO)
	@Column(name="token_id")
	private int tokenID;
	@Column(name="user_id", unique=true)
	private int userID;
	 
	@Column(name="authenticationToken")
	private String authenticationToken;
	@Column(name="secretKey")
	private String secretKey;
	@Column(name="email_id")
	private String emailId;
	public Token() { }
	public Token(int tokenID, int userID, String authenticationToken, String secretKey, String emailId) {
		super();
		this.tokenID = tokenID;
		this.userID = userID;
		this.authenticationToken = authenticationToken;
		this.secretKey = secretKey;
		this.emailId = emailId;
	}
	public int getTokenID() {
		return tokenID;
	}
	public void setTokenID(int tokenID) {
		this.tokenID = tokenID;
	}
	public int getUserID() {
		return userID;
	}
	public void setUserID(int userID) {
		this.userID = userID;
	}
	public String getAuthenticationToken() {
		return authenticationToken;
	}
	public void setAuthenticationToken(String authenticationToken) {
		this.authenticationToken = authenticationToken;
	}
	public String getSecretKey() {
		return secretKey;
	}
	public void setSecretKey(String secretKey) {
		this.secretKey = secretKey;
	}
	public String getEmailId() {
		return emailId;
	}
	public void setEmailId(String emailId) {
		this.emailId = emailId;
	}
	@Override
	public String toString() {
		return "Token [tokenID=" + tokenID + ", userID=" + userID + ", authenticationToken=" + authenticationToken
				+ ", secretKey=" + secretKey + ", emailId=" + emailId + "]";
	}
}

创建DAO接口
在这里,我们将创建两个DAO接口以执行与数据库相关的操作。

AdminDAO.java

package com.w;3codebox.LoginLogoutExample.DAO.interfaces;
import java.util.List;
import com.w3codebox.LoginLogoutExample.entity.AdminDetail;
public interface AdminDAO {
	public int saveAdminDetail(AdminDetail adminDetail);
	public int adminLogin(String emailId, String password);
	public List<AdminDetail> getAdminData();
}

TokenDAO.java

package com.w;3codebox.LoginLogoutExample.DAO.interfaces;
public interface TokenDAO {
	public void saveUserEmail(String email, int adminId);
	public boolean updateToken(String email, String authenticationToken, String secretKey);
	public int getTokenDetail(String email);
	public int tokenAuthentication(String token, int emailId);
}

创建DAO接口实现类

AdminDAOImpl.java

package com.w;3codebox.LoginLogoutExample.DAO.implementation;
import java.util.List;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.query.Query;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import com.w3codebox.LoginLogoutExample.DAO.interfaces.AdminDAO;
import com.w3codebox.LoginLogoutExample.entity.AdminDetail;
@Repository("adminDAO")
public class AdminDAOImpl implements AdminDAO {
	// Autowired SessionFactory Object So that we can get session object used for interaction with Database.
	@Autowired
	private SessionFactory sessionFactory;
	/*
	 * Enregistrer les détails de l'administrateur. 
	*/
	public int saveAdminDetail(AdminDetail adminDetail) {
		Session session = null;
		try
		{
			session = sessionFactory.getCurrentSession();
			int id = (Integer) session.save(adminDetail);
			return id;
		}
		catch(Exception exception)
		{
			System.out.println("Exception while saving admin Details : "); + exception.getMessage());
			return 0;
		}
		finally
		{
			session.flush();
		}
	}
	public int adminLogin(String emailId, String password) {
		Session session = null;
		try
		{
			session = sessionFactory.getCurrentSession();
			Query query = session.createQuery("from AdminDetail where emailId=:emailId and password=:password");
			query.setParameter("emailId", emailId);
			query.setParameter("password", password);
			List<AdminDetail> list = query.list();
			int size = list.size();
			if(size == 1)}}
			{
				return list.get(0).getAdminID();
			}
			else
			{
				return -1;
			}
		}
		catch(Exception exception)
		{
			System.out.println("Exception while saving admin Details : "); + exception.getMessage());
			return 0;
		}
		finally
		{
			session.flush();
		}
	}
	public List<AdminDetail> getAdminData() {
		Session session = null;
		try
		{
			session = sessionFactory.getCurrentSession();
			Query<AdminDetail> query = session.createQuery("from AdminDetail");
			List<AdminDetail> list = query.list();
			if(list.size() > 0)
			{
				return list;
			}
			else
			{
				return null;
			}
		}
		catch(Exception exception)
		{
			System.out.println("Exception while saving admin Details : "); + exception.getMessage());
			return null;
		}
		finally
		{
			session.flush();
		}
	}
}

TokenDAOImpl.java

package com.w;3codebox.LoginLogoutExample.DAO.implementation;
import java.util.List;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.query.Query;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import com.w3codebox.LoginLogoutExample.DAO.interfaces.TokenDAO;
import com.w3codebox.LoginLogoutExample.entity.Token;
@Repository("tokenDAO")
public class TokenDAOImpl implements TokenDAO {
	@Autowired
	SessionFactory sessionFactory;
	public void saveUserEmail(String email, int adminId) {
		Session session = null; 
		try
		{
			session = sessionFactory.getCurrentSession();
			Token t = new Token();
			t.setUserID(adminId);
			t.setEmailId(email);
			session.save(t); 
		}
		catch(Exception exception)
		{
			System.out.println("Exception in saving UserEmail In Token Table :: "); + exception.getMessage());
		}
		finally
		{
			session.flush();
		}
	}
	public boolean updateToken(String email, String authenticationToken, String secretKey) {
		Session session = null;
		try 
		{
			session = sessionFactory.getCurrentSession();
			Query theQuery = null;		
			theQuery = session.createQuery("Update Token set authenticationToken = :authenticationToken, secretKey = :secretKey where emailId = :userEmail ");
			theQuery.setParameter("authenticationToken", authenticationToken);
			theQuery.setParameter("userEmail", email);
			theQuery.setParameter("secretKey", secretKey);
			int result = theQuery.executeUpdate();
			si (result == 1)}}
			{
				return true;
			}
			else
			{
				return false;
			}
		}
		catch(Exception exception)
		{
			System.out.println("Error while updating token :: "); + exception.getMessage());
			return false;
		}
		finally
		{
			session.flush();
		}			
	}
	public int getTokenDetail(String email) {
		Session session = null;
		try
		{
			session = sessionFactory.getCurrentSession();
			Query<Token> query = session.createQuery("from Token where emailId = :userEmail");
			query.setParameter("userEmail", email);
			List<Token> tokenDetails = query.list();
			if(tokenDetails.size() > 0)
			{
				return tokenDetails.get(0).getTokenID();
			}
			else
			{
				return 0;
			}
		}
		catch(Exception exception)
		{
			System.out.println("Exception while getting token ID :: "); + exception.getMessage());		
		}
		finally
		{
			session.flush();
		}
		return 0;
	}
	public int tokenAuthentication(String token, int emailId) {
		Session session = null;
		try 
		{
			session = sessionFactory.getCurrentSession();
			Query query = session.createQuery("from Token where userID = :userID and authenticationToken = :token");
			query.setParameter("userID", emailId);
			query.setParameter("token", token);
			List<Token> tokenDetails = query.list();
			if(tokenDetails.size() > 0)
			{
				return tokenDetails.get(0).getTokenID();
			}
			else
			{
				return 0;
			}
		}
		catch(Exception exception)
		{
			System.out.println("Exception while Authenticating token :: ");+ exception);
			return 0;
		}
		finally
		{
			session.flush();
		}
	}
}

创建服务层接口

在这里,我们正在创建充当DAO和Entity类之间桥梁的服务层接口。

AdminService.java

package com.w;3codebox.LoginLogoutExample.service.interfaces;
import java.util.List;
import com.w3codebox.LoginLogoutExample.entity.AdminDetail;
public interface AdminService {
	public int saveAdminDetail(AdminDetail adminDetail);
	public int adminLogin(String emailId, String password);
	public List<AdminDetail> getAdminData();
}

TokenService.java

package com.w;3codebox.LoginLogoutExample.service.interfaces;
public interface TokenService {
	public void saveUserEmail(String email, int adminId);
	public boolean updateToken(String email, String authenticationToken, String secretKey);
	public int getTokenDetail(String email);
	public int tokenAuthentication(String token, int emailId);
}

创建服务层实现类

AdminServiceImpl.java

package com.w;3codebox.LoginLogoutExample.service.implementation;
import java.util.List;
import javax.transaction.Transactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.w3codebox.LoginLogoutExample.DAO.interfaces.AdminDAO;
import com.w3codebox.LoginLogoutExample.entity.AdminDetail;
import com.w3codebox.LoginLogoutExample.service.interfaces.AdminService;
@Service("adminService")
public class AdminServiceImpl implements AdminService {
	@Autowired
	private AdminDAO adminDAO;
	@Transactional
	public int saveAdminDetail(AdminDetail adminDetail) {
		return adminDAO.saveAdminDetail(adminDetail);
	}
	@Transactional
	public int adminLogin(String emailId, String password) {
		return adminDAO.adminLogin(emailId, password);
	}
	@Transactional
	public List<AdminDetail> getAdminData() {
		return adminDAO.getAdminData();
	}
}

TokenServiceImpl.java

package com.w;3codebox.LoginLogoutExample.service.implementation;
import javax.transaction.Transactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.w3codebox.LoginLogoutExample.DAO.interfaces.TokenDAO;
import com.w3codebox.LoginLogoutExample.service.interfaces.TokenService;
@Service("tokenService")
public class TokenServiceImpl implements TokenService {
	@Autowired
	private TokenDAO tokenDAO;
	@Transactional
	public void saveUserEmail(String email, int adminId) {
		tokenDAO.saveUserEmail(email, adminId);
	}
	@Transactional
	public boolean updateToken(String email, String authenticationToken, String secretKey) {
		return tokenDAO.updateToken(email, authenticationToken, secretKey);
	}
	@Transactional
	public int getTokenDetail(String email) {
		return tokenDAO.getTokenDetail(email);
	}
	@Transactional
	public int tokenAuthentication(String token, int emailId) {
		return tokenDAO.tokenAuthentication(token, emailId);
	}
}

Classe de création de jeton

GenerateToken.java

package com.javavtpoint.LoginLogoutExample.Token;
import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.DatatypeConverter;
import java.security.Key;
import java.util.Date;
import java.util.Random;
import io.jsonwebtoken.*;
public class GenerateToken {
public String[] createJWT(String id, String issuer, String subject, String role, long ttlMillis) {
	    //L'algorithme de signature JWT que nous utiliserons pour signer le jeton
	    SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
	 
	    long nowMillis = System.currentTimeMillis();
	    Date now = new Date(nowMillis);
	    
		Random random = new Random();
		String secretKey = id  + Integer.toString(random.nextInt(1000));
	    byte[] apiKeySecretBytes = DatatypeConverter.parseBase64Binaire(secretKey);
	    
	    La clé de signatureKey = null;
	    try{
	    	
	    	signingKey = new SecretKeySpec(apiKeySecretBytes, signatureAlgorithm.getJcaName());
	    }
	    catch(Exception e)
	    {
	    	System.out.println("Exception while generating key " + e.getMessage() );
	    }
	    
	    JwtBuilder builder = Jwts.builder().setId(id)
	                                .setIssuedAt(now)
	                                .setSubject(subject)
	                                .setIssuer(issuer)
	                                .setPayload(role)
	                                .signWith(signatureAlgorithm, signingKey);
	    
	    //si elle a été spécifiée, ajoutons l'expiration
	    if (ttlMillis >= 0) {
	    long expMillis = nowMillis + ttlMillis;
	        Date exp = new Date(expMillis);
	        builder.setExpiration(exp);
	    }
	    
	    String[] tokenInfo = {builder.compact() , secretKey};
	    return tokenInfo;
	    
	}
}

Créer une classe de contrôleur

AdminController.java

package com.w;3codebox.LoginLogoutExample.restController;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.w3codebox.LoginLogoutExample.entity.AdminDetail;
import com.w3codebox.LoginLogoutExample.service.interfaces.AdminService;
import com.w3codebox.LoginLogoutExample.service.interfaces.TokenService;
import com.javavtpoint.LoginLogoutExample.Token.GenerateToken;
@RestController
@RequestMapping("/api")
@CrossOrigin(origins = "http://localhost:4200	nallowedHeaders = "*"	exposedHeaders = "Authorization")
public class AdminController {
	@Autowired
	private AdminService adminService;
	@Autowired
	private TokenService tokenService;
	GenerateToken generateToken = new GenerateToken();
	@PostMapping("/saveAdmin")
	public int saveAdminDetail(@RequestBody AdminDetail adminDetail) {
		return adminService.saveAdminDetail(adminDetail);
	}
	@PostMapping("/login")
	public ResponseEntity<Integer> login(@RequestBody AdminDetail adminDetail)
	{
		int status;
		HttpHeaders httpHeader = null;
		// Authentifiez l'utilisateur.
		status = adminService.adminLogin(adminDetail.getEmailId(), adminDetail.getPassword());
		/*
		 * Si l'utilisateur est authentifié, effectuez la tâche d'autorisation.
		 */
		if (status > 0) 
		{
			/*
			 * Générez le jeton.
			 */
			String tokenData[] = generateToken.createJWT(adminDetail.getEmailId(), "w3codebox", "JWT Token",
					adminDetail.getRole(), 43200000);
			// Obtenez le Token.
			String token = tokenData[0];
			System.out.println("Authorization :: " + token);
			// Créez l'Objet Header
			httpHeader = new HttpHeaders();
			// Ajoutez le jeton au Header.
			httpHeader.add("Authorization", token);
			// Vérifiez si le jeton existe déjà.
			long isUserEmailExists = tokenService.getTokenDetail(adminDetail.getEmailId());
			/*
			 * Si le jeton existe, mettez à jour le Token sinon créez et insérez le jeton.
			 */
			if (isUserEmailExists > 0)} 
			{
				tokenService.updateToken(adminDetail.getEmailId(), token, tokenData[1]);
			} 
			else 
			{
				tokenService.saveUserEmail(adminDetail.getEmailId(), status);
				tokenService.updateToken(adminDetail.getEmailId(), token, tokenData[1]);
			}
			return new ResponseEntity<Integer>(status, httpHeader, HttpStatus.OK);
		} 
		// si non authentifié retournez status ce que nous obtenons.
		else 
		{
			return new ResponseEntity<Integer>(status, httpHeader, HttpStatus.OK);
		}
	}
	@GetMapping("/getAdminData/{adminId}
	public List<AdminDetail> getAdminData(@PathVariable int adminId, @RequestHeader("Authorization") String authorizationToken)
	{
		String token[] = authorizationToken.split(" ");
		int result = tokenService.tokenAuthentication(token[1], adminId);
		if (result > 0) {
			return adminService.getAdminData();
		} else {
			return null;
		}
	}
}

Créer un fichier de propriétés

Ici, nous créons le fichier de propriétés du projet. src/main/resources dans lequel les fichiers de propriétés sont créés. Les fichiers suivants contiennent la configuration des connexions dormantes.

persistence-mysql.properties

## Propriétés de connexion JDBC
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/loginlogoutexample?useSSL=false
jdbc.user=root
jdbc.password=
## Propriétés du pool de connexion
connection.pool.initialPoolSize=5
connection.pool.minPoolSize=5
connection.pool.maxPoolSize=20
connection.pool.maxIdleTime=3000
## Propriétés Hibernate #
<!-- hibernate.dialect=org.hibernate.dialect.MySQLDialect -->
hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
hibernate.show_sql=true
hibernate.format_sql=true
hibernate.hbm2ddl=update
hibernate.packagesToScan=com.w3codebox.LoginLogoutExample.entity

Module Angular

Voyons la structure de répertoires d'Angular:

Créer un projet Angular

Laissez-nous utiliser la commande suivante pour créer un projet Angular:

Ici, LoginLogoutExample est le nom

Installer le cadre CSS Bootstrap

Utilisez la commande suivante pour installer Bootstrap dans le projet.

npm install bootstrap @ 3.3.7 --enregistrer

Maintenant, incluez le code suivant dans le fichier style.css.

@import "~bootstrap/dist/css/bootstrap.css";

Générer le composant
Ouvrez le projet dans Visual Studio puis utilisez les commandes suivantes pour générer les composants Angular suivants:
ng gc page d'accueil
ng gc connexion
ng gc enregistrement
ng gc fichier de configuration

Nous utilisons également les commandes suivantes pour créer les classes de service: -

ng gs services/Admin

Éditer app.module.ts Fichier Mettre en œuvre le routage-Ici, nous devons importer @ angular/router du paquet RouterModule et définir le chemin dans le tableau d'importation. Importation de ReactiveFormsModule -Ici, nous allons importer ReactiveFormsModule pour réagir aux formes, et le spécifier dans le tableau imports. Importation de HttpModule -Ici, nous importons le HttpModule pour les requêtes serveur HttpModule et le spécifier dans le tableau import. Enregistrer le type de service-Ici, nous avons mentionné le type de service dans le tableau des fournisseurs.

import { BrowserModule } from '@angular'/platform-browser';
import { NgModule } from '@angular',/core';
// import Http module
import { HttpModule} from '@angular',/http';
// import ReactiveFormsModule for reactive form
import { ReactiveFormsModule } from '@angular',/forms';
// import module for Routing.
import { RouterModule } from '@angular',/router';
import { AppComponent } from '.',/app.component';
import { LoginComponent } from '.',/login/login.component';
import { HomeComponent } from '.',/home/home.component';
import { SignupComponent } from '.',/signup/signup.component';
import { AdminService } from '.',/services/admin.service';
import { ProfileComponent } from '.',/profile/profile.component';
@NgModule({
  declarations: [
    AppComponent,
    LoginComponent,
    HomeComponent,
    SignupComponent,
    ProfileComponent
  ],
  imports: [
    BrowserModule,
    ReactiveFormsModule,
    HttpModule,
    RouterModule.forRoot([
      {
        path : '',
        component : HomeComponent 
      },
      {
        path : 'login',
        component : LoginComponent  
      },
      {
        path : 'signup',
        component : SignupComponent 
      },
      {
        path: 'profile'/:adminId',
        component: ProfileComponent
      }
    ])
  ],
  providers: [
    AdminService
  ],
  bootstrap: [AppComponent]
}
export class AppModule { }

Éditer app.component.html Fichier

<router-outlet></router-outlet>

Éditer home.component.html Fichier
C'est la page d'accueil de l'application, qui comprend deux liens-"S'inscrire" et "Se connecter".

<div style="text-align: center">
    <h2>  <a [routerLink]="['/signup']">SignUp</a> <br><br> </h2>
    <h2>  <a [routerLink]="['/login']">Login</a> <br><br> </h2>
    
</div>

Créer AdminDetail.ts Classe

Utilisons la commande suivante pour créer une classe: -

Maintenant, dans AdminDetail Spécifiez les champs obligatoires dans la classe.

export class AdminDetail {
    emailId: string;
    name: string;
    password: string;
    role: string;
}

L'objectif de cette classe est de mapper les champs spécifiés avec les champs des classes d'entités Spring.

Éditer admin.service.ts Fichier

import { Injectable } from '@angular/core';
import { Http, RequestOptions, Headers } from '@angular/http';
import { Observable } from 'rxjs';
import { AdminDetail } from "../classes/admin-detail';
import { Router } from "@angular/router';
import { JwtHelperService } from '@auth0/angular-jwt';
@Injectable({
  providedIn: 'root'
}
export class AdminService {
  // Base URL
  private baseUrl = "http://localhost:8080/LoginLogoutExample/api/";"
  
  constructor(private http: Http, private router: Router) { }
  saveAdminDetails(adminDetail : AdminDetail) : Observable<any>
  {
      let url = this.baseUrl + "saveAdmin";
      return this.http.post(url,adminDetail);
  }
  login(adminDetail : AdminDetail) : Observable<any>
  {
      let url = this.baseUrl + "login";
      return this.http.post(url, adminDetail);
  }
  logout() 
  { 
    // Retirez le jeton du localStorage.
    localStorage.removeItem('token');
    this.router.navigate(['']);
  }
  /*
  * Vérifiez si l'utilisateur est connecté ou non.
  */
  isLoggedIn() { 
    // Créez une instance de la classe JwtHelper.
    let jwtHelper = new JwtHelperService();
    // Obtenez le jeton à partir du localStorage car nous devons travailler sur ce jeton.
    let token = localStorage.getItem('token');
    // Vérifiez si le jeton contient quelque chose ou s'il est null.
    if(!token)
    {
      return false;
    }
    // Obtenez la date d'expiration du jeton en appelant la méthode getTokenExpirationDate(String) de la classe JwtHelper. Cette méthode accepte une valeur de chaîne qui n'est rien d'autre qu'un jeton.
    if(token)
    {
      let expirationDate = jwtHelper.getTokenExpirationDate(token);
      // Vérifiez si le jeton est expiré ou non en appelant la méthode isTokenExpired() de la classe JwtHelper.
      let isExpired = jwtHelper.isTokenExpired(token);
      return !isExpired;    
    }   
  }
  
  
  getAdminDetail(adminId) : Observable<any>
  {
      let url = this.baseUrl + "getAdminData/" + adminId;
       // create an instance of Header object.
      let headers = new Headers();
      // get token from localStorage.
      let token = localStorage.getItem('token');
      // Append Authorization header.
      headers.append('Authorization', 'Bearer ') + token);
      // create an object of RequestOptions and include that in it.
      let options = new RequestOptions({ headers: headers });
      return this.http.get(url, options);
  }
  
}

Éditer signup.component.ts Fichier

import { Component, OnInit } from '@angular/core';
import { FormGroup, FormControl, Validators } from '@angular/forms';
import { AdminDetail } from "../classes/admin-detail';
import { AdminService } from '../services/admin.service';
import { Router } from "@angular/router';
@Component({
  selector: 'app-signup',
  templateUrl: "./signup.component.html',
  styleUrls: ["./signup.component.css'
}
export class SignupComponent implements OnInit {
  private adminDetail = new AdminDetail();
  constructor(private adminService: AdminService, private router: Router) { }
  ngOnInit() {
  }
  // créer l'objet du formulaire.
  form = new FormGroup({
      fullName : new FormControl('', Validators.required),
      email : new FormControl('', Validators.required),
      password : new FormControl('', Validators.required),
      confirmPassword : new FormControl('', Validators.required),
      role : new FormControl('', Validators.required),
  });
  AdminForm(AdminInformation)
  {
     let pass = this.Password.value;
     let confirmPass = this.ConfirmPassword.value;
     if(pass == confirmPass)
     {
        this.adminDetail.name = this.FullName.value;
        this.adminDetail.emailId = this.Email.value;
        this.adminDetail.password = this.Password.value;
        this.adminDetail.role = this.Role.value;
        this.adminService.saveAdminDetails(this.adminDetail).subscribe(
          response => {
              let result = response.json();
              si (result > 0)
              {
                this.router.navigate(['/login']);
              }
              else
              {
                  alert("Une erreur s'est produite lors de l'enregistrement de l'utilisateur. Veuillez réessayer après un certain temps.")
              }
          },
          error => {
            alert("Une erreur s'est produite lors de l'enregistrement de l'utilisateur. Veuillez réessayer après un certain temps.")
          }
        );
        
     }
     else
     {
        alert("Le mot de passe et la confirmation du mot de passe ne correspondent pas.");
     }
  }
  get FullName(){
    return this.form.get('fullName');
  }
  get Email(){
      return this.form.get('email');
  }
  get Password(){
      return this.form.get('password');
  }
  get ConfirmPassword(){
      return this.form.get('confirmPassword');
  }
  get Role(){
      return this.form.get('role');
  }
}

Éditer signup.component.html Fichier

<h2>Formulaire d'inscription </h2>
<form [formGroup]="form" #AdminInformation (ngSubmit)="AdminForm(AdminInformation)">
  <div class="row">
    <div class=" col-md-offset-1 col-md-4">
        <label for="fullName"> Nom </label>
        <input formControlName="fullName" class="form-control" type="text"> 
    </div>
  </div>
  <div class="row">
    <div class=" col-md-offset-1 col-md-4">
        <label for="email"> Email </label>
        <input formControlName="email" class="form-control" type="text"> 
    </div>
  </div>
  <div class="row">
    <div class=" col-md-offset-1 col-md-4">
        <label for="password"> Password </label>
        <input formControlName="password" class="form-control" type="password"> 
    </div>
  </div>
  <div class="row">
    <div class=" col-md-offset-1 col-md-4">
        <label for="confirmPassword"> Confirmez le mot de passe </label>
        <input formControlName="confirmPassword" class="form-control" type="password"> 
    </div>
  </div>
  <div class="row">
    <div class=" col-md-offset-1 col-md-4">
        <label for="role"> Rôle </label>
        <input formControlName="role" class="form-control" type="text"> 
    </div>
  </div>
  <div class="row" style="margin-top: 40px;">
    <div class="col-md-offset-1 col-md-4">
        <button class="btn btn-md btn-primary btn-style"  >Enregistrer</button>
    </div>
  </div>
</form>

Éditer login.component.ts Fichier

import { Component, OnInit } from '@angular/core';
import { FormGroup, Validators, FormControl } from "@angular/forms';
import { AdminDetail } from "../classes/admin-detail';
import { AdminService } from '../services/admin.service';
import { Router } from "@angular/router';
@Component({
  selector: 'app-login',
  templateUrl: "./login.component.html',
  styleUrls: ["./login.component.css"]
}
export class LoginComponent implements OnInit {
  private adminDetail = new AdminDetail();
  constructor(private adminService: AdminService, private router: Router) { }
  ngOnInit() {
    if((this.adminService.isLoggedIn())
    {
        this.router.navigate(['/profile', localStorage.getItem('id')]);
    }
    else
    {
        this.router.navigate(['/login']);
    }
  }
  // créer l'objet du formulaire.
  form = new FormGroup({
    email : new FormControl('', Validators.required),
    password : new FormControl('', Validators.required)
  });
  Login(LoginInformation)
  {
      this.adminDetail.emailId = this.Email.value;
      this.adminDetail.password = this.Password.value;
      this.adminService.login(this.adminDetail).subscribe(
        response => {
            let result = response.json();
            
            si (result > 0)
            {
              let token = response.headers.get("Authorization");
              localStorage.setItem("token", token);
              localStorage.setItem("id", result);
  
              this.router.navigate(['/profile', result]);
            }
            si (result == -1)}}
            {
              alert("please register before login Or Invalid combination of Email and password");
            }
           
        },
        error => {
            console.log("Error in authentication");
        }
      );
  }
  get Email(){
      return this.form.get('email');
  }
  get Password(){
      return this.form.get('password');
  }
}

Éditer login.component.html Fichier

<h2>Login form</h2>
<form [formGroup]="form" #LoginInformation (ngSubmit)="Login(LoginInformation)">
  <div class="row">
    <div class=" col-md-offset-1 col-md-4">
        <label for="email"> Email </label>
        <input formControlName="email" class="form-control" type="text"> 
    </div>
  </div>
  <div class="row">
    <div class=" col-md-offset-1 col-md-4">
        <label for="password"> Password </label>
        <input formControlName="password" class="form-control" type="password"> 
    </div>
  </div>
  <div class="row" style="margin-top: 40px;">
    <div class="col-md-offset-1 col-md-4">
        <button class="btn btn-md btn-primary btn-style"  >Login</button>
    </div>
  </div>
</form>

Éditer profile.component.ts Fichier
Après la connexion de l'utilisateur, il redirigera vers le composant de fichier de configuration.

import { Component, OnInit } from '@angular/core';
import { AdminService } from '../services/admin.service';
import { ActivatedRoute, Router } from '@angular/router';
@Component({
  selector: 'app-profile',]}
  templateUrl: "./profile.component.html",
  styleUrls: ["./profile.component.css"]
}
export class ProfileComponent implements OnInit {
  private adminId;
  private haveData= 0;
  private data = [];
  private dataRequest = false;
  constructor(private adminService : AdminService, private route : ActivatedRoute, private router : Router) { }
  ngOnInit() {
    if((this.adminService.isLoggedIn())
    {
      this.route.paramMap.subscribe(params => {
        this.adminId =+ params.get('adminId');
      });
    }
    else
    {
        this.router.navigate(['/login']);
    }
  }
  getAdminData()
  {
      this.haveData = 0;
      this.dataRequest = true;
      this.adminService.getAdminDetail(this.adminId).subscribe(
          response => {
              let result = response.json();
              this.data = result;
              if(result == " ")
              {
                  this.haveData = 0;
              }
              else
              {
                this.haveData = this.haveData + 1;
              }
          },
          error => {
              console.log("error while getting Admin Data");
          }
      );
  }
}

Éditer profile.component.html Fichier

<div style="text-align: right; margin-droite: 40px;">
  <h2> <a (click)= "adminService.logout()">Logout</a><br></h2>
  
</div>
<div style="text-align: center; margin-droite: 40px;">
  <h2><a (click)="getAdminData()">Détails administratifs obtenir</a>/a><br></h2>
  
</div>
<div *ngIf="haveData > 0 && dataRequest">
    <table class="table table-tableau réactif-striped">
        <tr>
          <th>ID Email</th>/th>
          <th>Nom</th>/th>
          <th>Mot de passe</th>/th>
          <th>Rôle</th>/th>
        </tr>
        
        <ng-container *ngfor = "let item of data"
            <tr>
              <td>{{item.emailId}}</td>/td>
              <td>{{item.name}}</td>/td>
              <td>{{item.password}}</td>/td>
              <td>{{item.role}}</td>/td>
            </tr>
        </ng-container>
  
      </table>
</div>
<div *ngIf="haveData == 0 && dataRequest">
    Pas de données.
</div>

L'utilisateur peut cliquer surDétails administratifs obtenirlien pour obtenir des détails administratifs.

Maintenant, l'utilisateur peut cliquer surDéconnexionÉtat actuel de sortie.