Previous Lecture Complete and continue  

  Lesson 3: Remember Me with Persistence

1. Main Goal

The focus of this lesson is to switch from the cookie based remember-me implementation to the persistence backed implemented that the framework provides.


2. Lesson Notes

The relevant module you need to import when you're starting with this lesson is: m3-lesson3

If you want to skip and see the complete implementation, feel free to jump ahead and import: m3-lesson4

A quick note is that this lesson is using MySQL, so you'll need to naturally have a MySQL Server running locally.

The credentials used in the code of this lesson are: test@email.com/pass (data.sql).


2.1. The Theory

The persistence backed implementation of remember-me is more secure than its cookie based counterpart with a mechanism that no longer relies on both username and passsword.

Now, only the username is exposed to the client and the password is never present in the cookie.

And as a direct consequence, if a cookie gets compromised, it's enough the delete the persisted tokens and the user no longer needs to change their password to invalidate issued tokens.

Next - the new remember me mechanism no longer validates the signature being present in the cookie - but the fact that the token is present in the DB.


2.2. The Implementation

Let's start by switching our persistence over to using MySQL just so that we can easily check the DB and see these tokens.

We're first going to define the MySQL dependency in Maven:

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
</dependency>

We are going to make use of Boot and the application.properties file to configure our persistence to use MySQL:

spring.datasource.url=jdbc:mysql://localhost/lss33?createDatabaseIfNotExist=true
spring.datasource.username=restUser
spring.datasource.password=restmy5ql
spring.datasource.driver-class-name=com.mysql.jdbc.Driver

Now, over in our security configure, we are going to wire in the data source and start using it when defining a persistence repository for our tokens:

@Autowired
private DataSource dataSource;
@Bean
public PersistentTokenRepository persistentTokenRepository() {
    JdbcTokenRepositoryImpl jdbcTokenRepository = new JdbcTokenRepositoryImpl();
    jdbcTokenRepository.setDataSource(dataSource);
    return jdbcTokenRepository;
}

Finally, we're going to make the switch from the cookie based implementation to the persistence backed one:

.tokenRepository(persistentTokenRepository())


2.3. The DB Structure

Before we run everything, we need to make sure the DB structure necessary for storing our tokens is created as well:

create table if not exists persistent_logins (
  username varchar_ignorecase(100) not null,
  series varchar(64) primary key,
  token varchar(64) not null,
  last_used timestamp not null
);

We can make use of the data.sql file that Spring Boot uses by default for setting up data on startup here.

But, keep in mind that there are a lot of options to set up an initial DB structure when a project starts up - besides Spring Boot.


2.4. The Series

Finally, one quick note - I touched on the concept of the series in the video.

This series field identifies the login of the user and doesn't change for duration of the entire persistent session.

It also contains a random token, regenerated each time a user logs in via the persisted remember-me functions.

The goal is to make brute force attacks impossible in practice.


3. Resources

- Remember-Me - Persistent Token Approach (in the Official Reference)

- Persistent Remember-Me on Baeldung

- Improved Persistent Login Cookie Best Practice

Module 3 - Lesson 3 - transcript.pdf