Workflow Social Auth and Spa?


#1

Hi, i have a question about SPA and Social Auth

So when

user press as example “Login with Facebook” i redirect the user to the facebook redirect url and then it hits the Server? but i have no idea how to tell my SPA to get the JWT

async providerCallback ({
    params,
    ally,
    auth,
    response
  }) {
    try {
      const socialUser = await ally.driver(params.provider).getUser()
      const userDetails = {
        email: socialUser.getEmail(),
        token: socialUser.getAccessToken(),
        provider: params.provider
      }

      const whereClause = {
        email: socialUser.getEmail()
      }

      const user = await User.findOrCreate(whereClause, userDetails)
      const token = await auth.generate(user)

      return token
    } catch (error) {
      console.log(error)
    }
  }

maybe i need a way to get just the access_token from facebook direct and validate it on the server Save the user and create the jwt token

i just cant get my head around this

thanks


#2

Having the same problem myself. Did you figure this out?


#3

You may use Facebook JS SDK for this.
Basically the workflow will look like this:

  1. You get user accessToken using FB.login
  2. You send it to your server
  3. You server endpoint gets accessToken and gets user via ally.getUserByToken (docs).
  4. Your server gets user by token returns JWT token

    For example I did it like this:
async token ({ request, response, params, auth, ally }) {

    const providers = Env.get('APP_AUTH_PROVIDERS', '').split(',')
    const { provider } = params
    const { access_token } = request.all()

    // check if requested provider is in the list
    if ( !providers.includes( provider ) ) {
      return response.badRequest({ message: 'Wrong provider.' })
    }

    // get provider user data
    const data = await ally.driver( provider ).getUserByToken(access_token)

    // combine data for new user
    const newUser = {
      email: data.getEmail(),
      password: Math.random().toString(18).substr(2, 8),
      provider: provider,
      // avatar: user.getAvatar(),
      // username: data.getName()
    }

    // find user
    let user = await User.query().where('email', data.getEmail() ).first()

    // if no user, create
    if ( !user ) {
      user = await User.create( newUser )
    }

    // trying to login user
    try {
      const token = await auth
        .authenticator('jwt')
        .withRefreshToken()
        .generate( user )

      return response.ok({ message: 'Logged in successfully.', data: { user, auth: token } })

    } catch (e) {
      return response.internalServerError({ message: e.message })
    }
  }

}