Domanda

I prefer not to write my own login function, so instead I would like to use openId. I found the library lightopenid and with some modifications of the google-example file it looks like this:

<?php
session_start();
# Logging in with Google accounts requires setting special identity, so this example shows how to do it.
require 'openid.php';
try {
    # Change 'localhost' to your domain name.
    $openid = new LightOpenID('127.0.0.1');
    if(!$openid->mode) {
        if(isset($_GET['login'])) {
            $openid->identity = 'https://www.google.com/accounts/o8/id';
            header('Location: ' . $openid->authUrl());
        }
?>
<form action="?login" method="post">
    <button>Login with Google</button>
</form>
<?php
    } elseif($openid->mode == 'cancel') {
        echo 'User has canceled authentication!';
    } else {
        echo 'User ' . ($openid->validate() ? $openid->identity . ' has ' : 'has not ') . 'logged in.';
        if ($openid->validate()) {
            $_SESSION['auth'] = true;
        }
    }
} catch(ErrorException $e) {
    echo $e->getMessage();
}

So I added a $_SESSION thing there... Now think I may use some code on the top of each protected page, like this:

<?php session_start(); 
if (!$_SESSION['auth']) { exit; } ?>

I want this to be done the right way, so that it's all safe and so on. Would you have done it this way or am I doing something wrong? I might use cookies instead...

È stato utile?

Soluzione

I haven't tried your code but if it's based upon the bundled Google example it should be just fine. Of course, with this code your site is not open to any OpenID owner, just Google users.

However, as you already note, LightOpenID only takes care of the authentication process so your application needs to collect and store the authentication details it needs, because it'd be a pain to authenticate again on each page request. The most important one is the identity. The identity is a URL and it's the OpenID equivalent of "login" or "username". As the "Configuracion" wiki page explains, you need to fetch it from $openid->identity right after successful validation, when it will change from https://www.google.com/accounts/o8/id to whatever unique URL Google has assigned to the user. You probably want to know it so:

  • You can assign different permissions to different users.
  • You're able to identify the user across different sessions.

Now, how should you store the identity?

  • Using a cookie to determine whether the user is authenticated is the worst possible solution. You don't need to be a hacker to break that—all modern browsers include easy-to-use GUI tools to edit cookies.

  • Server-side sessions are an industry standard. Following my remark about identity, I'd store at least this:

    $_SESSION['openid'] = $openid->identity;
    
  • In addition to sessions, you'll need a database if the user data you generate needs to persist across sessions. (That depends on your needs.)

Edit:

You cannot validate twice because the request expires. It's a security mechanism. Store it into a variable if you need to reuse it:

$is_valid = $openid->validate();
echo 'User ' . ($is_valid ? $openid->identity . ' has ' : 'has not ') . 'logged in.';
if ($is_valid) {
    $_SESSION['auth'] = true;
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top