Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

PHP PHP User Authentication Adding Authentication to Your Application Working with Cookies

Justin Sorensen
Justin Sorensen
14,734 Points

How to redirect with $content instead of passing null as the first parameter in our redirect function.

I'm not having any luck passing content to our first parameter in our redirect function.

I've modified our doLogin.php redirect call to look like this:

redirect('/', ['username' => $user['name'], 'cookies' => [$accessToken]]);

I'm modified our redirect function to look something like this in my redirect function:

if (key_exists('username', $extra)) {
        $response->setContent(json_encode(array(
            'username' => $extra['username'],
        )));
        $response->headers->set('Content-Type', 'application/json');
    }

Then in our index.php file I am trying to access that username content with:

$username = request()->getContent();

I have also tried this:

$username = request()->get('username');

Both methods are unsuccessful. I'm not understanding how to properly send content through the redirect. Please help. Thank you. Alena Holligan

Alena Holligan
Alena Holligan
Treehouse Teacher

You need to define $request before you use it. On index.php try

$request = \Symfony\Component\HttpFoundation\Request::createFromGlobals();
var_dump($request->getContent());
Justin Sorensen
Justin Sorensen
14,734 Points

Alena Holligan thanks for the answer. But isn't that what we have set up with our request() function? Inside of our /inc/functions.php we have the request function doing just that. So shouldn't we be able to do request()->getContent(); inside of index.php?

3 Answers

Alena Holligan
STAFF
Alena Holligan
Treehouse Teacher

yes the request() function should do the same thing.

What are you trying to do? you can pass headers, but you can't pass content if you're going to redirect. Headers (the redirect) is called before the content. You could add the username (which isn't in the supplied database) along with or instead of the user id in the JWT, or as it's own cookie or session

Justin Sorensen
Justin Sorensen
14,734 Points

Alena Holligan Ok that sounds like what I'm trying to do- send some data inside the JWT. If you can take a look at this snippet below I'm trying to not only pass the 'access_token' to the redirect function, I've prepended the username to the redirect function parameter array:

$jwt = \Firebase\JWT\JWT::encode([
    'iss' => request()->getBaseUrl(),
    'sub' => "{$user['id']}",
    'exp' => $expTime,
    'iat' => time(),
    'nbf' => time(),
    'is_admin' => $user['role_id'] == 1
], getenv("SECRET_KEY"),'HS256');
//define where the cookie lives, the last parameter if not set, cookie will live in session
$accessToken = new Symfony\Component\HttpFoundation\Cookie('access_token', $jwt, $expTime, '/', getenv('COOKIE_DOMAIN'));

$session->getFlashBag()->add('success', 'Successfully Logged In');
redirect('/', ['username' => $user['name'], 'cookies' => [$accessToken]]);

And then in my functions.php file for the redirect function I've got this:

function redirect($path, $extra = []) {
    $response = \Symfony\Component\HttpFoundation\Response::create(null, \Symfony\Component\HttpFoundation\Response::HTTP_FOUND, ['Location' => $path]);
    if (key_exists('cookies', $extra)) {
        foreach ($extra['cookies'] as $cookie) {
            $response->headers->setCookie($cookie);
        }
    }
    if (key_exists('username', $extra)) {
        $response->setContent(json_encode(array(
            'username' => $extra['username'],
        )));
        $response->headers->set('Content-Type', 'application/json');
    }
    $response->send();
    exit;
}

From the documentation in Symfony, that was how they recommended sending content like that. I've tried everything. Then in my index.php file you are supposed to be able to get that setContent with this:

$content = request()->getContent();

But I var_dump($content) and get nothing...

Thoughts?

Thank you.

Alena Holligan
STAFF
Alena Holligan
Treehouse Teacher

The content isn't the JWT. You would either:

  1. Edit the JWT itself when you you encode it

    $jwt = \Firebase\JWT\JWT::encode([
    'iss' => request()->getBaseUrl(),
    'sub' => "{$user['id']}",
    'username' => "{$user['username']}",
    'exp' => $expTime,
    'iat' => time(),
    'nbf' => time(),
    'is_admin' => $user['role_id'] == 1
    ], getenv("SECRET_KEY"),'HS256');
    
  2. Add a second cookie

    if (key_exists('username', $extra)) {
        $response->setCookie(
            'username' => $extra['username'],
        );
    }
    
  3. Set and get session attributes

    $session->set('username', $extra['username']);
    $session->get('username');
    
Justin Sorensen
Justin Sorensen
14,734 Points

Alena Holligan so these are three seperate solutions right? Thanks for the response. I think I'll go with solution number 1. Is one method prefereed over the other? I had not had any luck with method 2 or 3 just now, but 1 worked...

Alena Holligan
STAFF
Alena Holligan
Treehouse Teacher

yes they are three separate solutions, and it really depends on what you are trying todo. You could also make the "sub" the username as long as that is unique.