Previous button browser after login


#1

Hi!

I am French, sorry for the translation :wink:

When a user connects to the / login page, he is redirected to the protected page.
When he clicks on the previous browser button, he is redirected to the / login page.

// Middleware

class RedirectIfAuthenticated {
  async handle ({auth, request, response}, next) {
    try {
      await auth.check()
      return response.redirect('/')
    } catch (e) {}
    await next()
  }
}

// Routes.js

Route.group(() => {
  Route.get('/login', 'SessionController.login')
  Route.post('/login', 'SessionController.store')
}).middleware(['guest']) //RedirectIfAuthenticated

Route.group(() => {
  Route.get('/home', 'UserController.index')
  Route.get('/:username', 'UserController.show')
  Route.get('/logout', 'SessionController.delete')
}).middleware(['auth'])

I would like it to be redirected to the protected page.

Thank you


#2

for simple solution can you add this block before your main logic block to your SessionController.login method

if(await auth.check())  {
  response.redirect('/home');
  return;
} 

#3

I have this error :

InvalidSessionException

E_INVALID_SESSION: Invalid session

SessionController.login :

   async login({auth, view, response}) {
    if(await auth.check())  {
      response.redirect('/dashboard');
      return;
    }
    return response.redirect('/login')
  }

#4

I just tried, it worked.

This code block is seems odd. Where do you store sessions?

  async login({auth, view, response}) {
    if(await auth.check())  {
      response.redirect('/dashboard');
      return;
    }
    return response.redirect('/login')
  }

Can you check blog example


Additionally, are you sure that default authenticator inside config/auth.js file is session ?


#5

I store sessions with:
https://adonisjs.com/docs/4.1/authentication#_sessions

config session :
driver: Env.get('SESSION_DRIVER', 'cookie')

login view and post:

class SessionController {

  async login({auth, view, response}) {
    if(await auth.check()){
      response.redirect('/dashboard');
      return;
    }
    return response.redirect('/login')
  }

  async store({auth, request, response, session}){
    const { email, password } = request.all()
    try {
      await auth.attempt(email, password)
    } catch (e) {

      session.flashExcept(['password'])
      session.flash({ error: 'Vos identifiants sont incorrects.' })
      return response.redirect('/login')
    }
    return response.redirect('/dashboard') 
  }

}


#6

can you try this?


#7

Always the same problem

When a user logs in, he is redirected to the member page, but when he clicks on the previous browser button, the / login page appears with the form, even though he is already logged in.


#8

Hey! :wave:

This is a normal behaviour. When clicking the back button of your browser, it will display a cached version of the page.

You cannot control that if you don’t have frontend JavaScript to your application that hook the history behaviour.


#9

how to control the browser cache after login?


#10

When you render the login page, write the following code inside controller

response.vary('Cookie')

// and then
view.render('login')

#11

I still have the same problem:

  login({view, response}) {
    response.vary('cookie')
    return view.render('home.login')
  }

There are 3 tokens before the connection:


#12

Then please share a repo with the minimum code to reproduce the issue


#13

SessionController :

'use strict'

class SessionController {

  login({view, response}) {
    response.vary('Cookie')
    return view.render('home.login')
  }

  async store({auth, request, response, session}){
    const { email, password } = request.all()
    try {
      await auth.attempt(email, password)
    } catch (e) {
      session.flashExcept(['password'])
      session.flash({ error: 'Vos identifiants sont incorrects.' })
      return response.redirect('/login')
    }
    return response.redirect('/dashboard')
  }

  async delete({auth, response}){
    await auth.logout()
    return response.redirect('/')
  }

}

module.exports = SessionController

Routes :

Route.get('/', 'HomeController.index')
Route.group(() => {
  Route.get('/login', 'SessionController.login')
  Route.post('/login', 'SessionController.store')
}).middleware(['guest'])

Route.group(() => {
  Route.get('/dashboard', 'UserController.index')
  Route.get('/:username', 'UserController.show')
  Route.get('/logout', 'SessionController.delete')
}).middleware(['auth'])

Middleware guest :

class RedirectIfAuthenticated {
  async handle ({auth, request, response}, next) {
    try {
      await auth.check()
      return response.redirect('/')
    } catch (e) {}
    await next()
  }
}

module.exports = RedirectIfAuthenticated

Views login :

@layout('layout.app')

@section('content')
@set('title', 'Inscription')
<section id="loginbox">

      @if(flashMessage('error'))
      <p class="text-sm">{{ flashMessage('error') }}</p>
      @endif
    <form action="/login" method="post">
      {{ csrfField() }}
    email<input type="text" name="email">
    password<input type="password" name="password">
    <input type="submit" value="Connexion">
    </form>
</section>

@endsection

@section('scripts')
{{ script('js/home.js') }}
@endsection

Config sessions :

'use strict'

const Env = use('Env')

module.exports = {
  driver: Env.get('SESSION_DRIVER', 'cookie'),
  cookieName: 'adonis-session',
  clearWithBrowser: true,
  age: '2h',
  cookie: {
    httpOnly: true,
    sameSite: true,
    path: '/'
  },
  file: {
    location: 'sessions'
  },
  redis: 'self::redis.local'
}

#14

Hello, I’m using headers to fix this ‘problem’.

All you have to do is tell the browser to prevent caching of that particular page, on navigating to that route, it forces a refresh. I wrote an article on it.

Might be helpful to you.


#15

Thank you
how can I adapt the code so that users are not redirected to unauthenticated pages after clicking on the browser’s previous button, after the login (register)?


#16

Register the middleware globally.