0

How can i check if session id 066efd5a182729d6fdbd43cb3a80adde exists or not? (I know it existed at some point in the past, but I need to know if it still does or not)

session_exists("066efd5a182729d6fdbd43cb3a80adde")
? "this session exists" : "this session expired/got deleted/whatever";

PS This is not a duplicate of:

  • Check if session exists in php because that guy wanted to see if the current request contained a valid cookie session or not (his problem can be solved with session_status() == PHP_SESSION_NONE, mine cannot)
  • PHP if SESSION exists but is null - i don't even understand what he means by How I can check in PHP if SESSION exists but is null. , i certainly don't want to check if $_SESSION is null.
hanshenrik
  • 19,904
  • 4
  • 43
  • 89
  • 2
    You can just use `session_id() === '066efd5a182729d6fdbd43cb3a80adde'` – Doğukan Akkaya Jun 29 '23 at 22:10
  • 3
    For what reason do you need to know if the session exists? The answer will vary depending on that. – Sammitch Jun 29 '23 at 22:54
  • 1
    Where does the ID come from and what do you need to do with session? Because trying to determine if **current user** session is new or was already created can be done with plain session functions, but anything else implies a search in the session storage backend (files by default, but can be changed). – Álvaro González Jun 30 '23 at 07:46
  • @Sammitch given my answer below, i don't think the reason is relevant to the question, but I'll answer anyway. I'm implementing a remote website login system (similar to how you can login on StackOverflow.com with your gmail account instead of your StackOverflow account), and the web browser is redirected from a.com->b.com and b.com gives the web browser a token and redirects it back to a.com , then the web browser gives the token back to a.com and a.com at the server-side ask b.com if the token is valid. the token should be invalid if the web browser has logged out before a.com's server ask – hanshenrik Jul 01 '23 at 17:14
  • @ÁlvaroGonzález ID comes from a remote server calling my API. and the remote server got the id from a web browser. and the web browser originally got the id my website. (it's not quite as simple as that, but it's pretty close. currently the code looks like https://gist.github.com/divinity76/6ec2ab700cb51422bc6fc9940a9dfc6b ) – hanshenrik Jul 01 '23 at 17:32
  • I don't see how the session ID is relevant in that workflow at all. Rather than attempting to reimplement OAuth from scratch via vague description you should probably at least look at, if not implement, the OAuth spec and workflow. There are also a number of existing libraries to enable both OAuth provider and client functionality. – Sammitch Jul 01 '23 at 23:04

2 Answers2

3

How can i check if session id 066efd5a182729d6fdbd43cb3a80adde exists or not? (I know it existed at some point in the past, but I need to know if it still does or not)

As with any other session ID as well.

Ensure you have no session opened, then set the session_id($id) and start the session session_start(). You find $_SESSION populated if there is some data associated with that (new) session id.

Now, PHP has an option to change the session id on start if it does not exists (Cf. _session.use_strict_mode; use_strict_mode in php sessions). So comparing after start if the ID is unchanged will tell you if the session exists.

Then decide what you want to do with the previously (non-) existing session, like kill it with fire, unset the cookie etc. (depends on context.)

Given, you only want to check the session id:

assert(PHP_SESSION_NONE === session_status());
assert(empty(session_id()));

echo session_exists("066efd5a182729d6fdbd43cb3a80adde")
    ? "this session exists" : "this session has expired";

assert(PHP_SESSION_NONE === session_status());
assert(empty(session_id()));

without affecting HTTP response headers, including not setting session cookie headers, here an example function:

function session_exists(string $session_id): bool {
    session_id($session_id);
    session_start(['cache_limiter' => '', 'use_cookies' => false, 'use_strict_mode' => true,]);
    $exists = $session_id === session_id();
    $exists ? session_abort() && session_id('') : session_destroy();
    return $exists;
}

Take care, it is with no error handling, e.g. session_start() may return false which means there was a failure.

hakre
  • 193,403
  • 52
  • 435
  • 836
1

as long as you're using the php-redis session module, or the default php-built-in files session module:

function session_exists(string $session_id, ?array $stuff = null): bool
{
    // https://php.net/session_module_name
    // ini: https://php.net/session.save_handler
    $session_module_name = session_module_name();

    if ($session_module_name === 'files') {
        // https://php.net/session_save_path
        // ini: https://php.net/session.save_path
        $session_file = session_save_path() . '/sess_' . $session_id;
        clearstatcache(false, $session_file);
        return file_exists($session_file);
    }

    if ($session_module_name === 'redis') {
        $redis = $stuff['redis_connection'] ?? null;
        if ($redis === null) {
            $redis = new Redis();
            $host = session_save_path(); // tcp://redis:6379
            $port_needle = strrpos($host, ':');
            $port = substr($host, $port_needle + 1);
            $port = filter_var($port, FILTER_VALIDATE_INT);
            if ($port === false) {
                throw new Exception("Unable to parse port from session_save_path(): " . session_save_path());
            }
            $host = substr($host, 0, $port_needle);
            $redis->connect($host, $port);
        }
        return $redis->exists("PHPREDIS_SESSION:{$session_id}") > 0;
    }

    throw new BadFunctionCallException(__FUNCTION__ . ": Unknown/unsupported session module name: {$session_module_name}");
}

usage:

echo session_exists("066efd5a182729d6fdbd43cb3a80adde")
 ? "this session exists" : "this session has expired";
hakre
  • 193,403
  • 52
  • 435
  • 836
hanshenrik
  • 19,904
  • 4
  • 43
  • 89
  • 1
    Nice example, the null-coalesing operator ?? handles the array check, the saved three lines I've used to add comments to the manual. The slash ("/") works as directory separator on the Unix/Linux and Windows platforms. And as the focus is likely more on the Redis backend, commenting only that for files there is a caveat: [session.save_path](https://php.net/session.save_path) can have an optional N argument that determines the number of directory levels your session files will be spread around in. If in use the directory to locate the session file in depends on the session-id itself as well. – hakre Jul 02 '23 at 18:22
  • @hakre thank you! TIL! I can't really be arsed implementing full 100%files session.save_path support, because I'm not using it myself, and I have never seen anyone else use it either (but the simple configuration with a single directory for session files is common! it's the debian/ubuntu/derivatives default configuration! - as for Redis, that's the one I actually needed/use ^^) – hanshenrik Jul 03 '23 at 07:12
  • Oh, it was not my intention to trick you into extending it, just left it as a comment only in case someone considers this approach. Actually I did review [my answer](https://stackoverflow.com/a/76595912/367456) which was quite sloppy and also added some code that should work regardless of the session module in use as it is using the standard session functions. hth. – hakre Jul 03 '23 at 14:49