3

I would like to use amp-access in an AMP page to show or hide content based on whether the user is logged in.

When looking at the example(s) provided by the AMP project:

... it only shows how this would work with an existing externally hosted OAuth provider. It does not provide an example on how this would work in an environment where credentials are not stored in a 3rd party system - which makes it rather difficult to validate.

What I have so far (to keep this as simple as possible), is the following structure on the server :

index.html
|--auth/index.php
|--login/index.php
|--logout/index.php

index.html

<!doctype html>
<html amp>
        <head>

                <meta charset="utf-8">
                <meta name="viewport" content="width=device-width,minimum-scale=1,initial-scale=1">
                <link rel="canonical" href="index.html">

                <style amp-boilerplate>body{-webkit-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-moz-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-ms-animation:-amp-start 8s steps(1,end) 0s 1 normal both;animation:-amp-start 8s steps(1,end) 0s 1 normal both}@-webkit-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-moz-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-ms-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-o-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}</style><noscript><style amp-boilerplate>body{-webkit-animation:none;-moz-animation:none;-ms-animation:none;animation:none}</style></noscript>

                <script async src="https://cdn.ampproject.org/v0.js"></script>
                <script async custom-element="amp-access" src="https://cdn.ampproject.org/v0/amp-access-0.1.js"></script>
                <script async custom-element="amp-form" src="https://cdn.ampproject.org/v0/amp-form-0.1.js"></script>
                <script async custom-element="amp-analytics" src="https://cdn.ampproject.org/v0/amp-analytics-0.1.js"></script>

                <script id="amp-access" type="application/json">
                    {
                        "authorization": "https://yoursite.com/auth/?rid=READER_ID&url=CANONICAL_URL&ref=DOCUMENT_REFERRER&_=RANDOM",
                        "pingback": "https://yoursite.com/auth/?rid=READER_ID&url=CANONICAL_URL&ref=DOCUMENT_REFERRER&_=RANDOM",
                        "login": {
                          "sign-in": "https://yoursite.com/login/?rid=READER_ID&url=CANONICAL_URL",
                          "sign-out": "https://yoursite.com/logout"
                        },
                        "authorizationFallbackResponse": {
                            "error": true,
                            "access": false,
                            "subscriber": false
                        }
                    }
                </script>

        </head>

        <body>

                <section amp-access="subscriber">
                        <h2>Access Granted</h2>
                        <a on="tap:amp-access.login-sign-out">Logout</a>
                </section>

                <section amp-access="NOT subscriber">
                        <h2>Permission Required</h2>
                        <a on="tap:amp-access.login-sign-in">Login</a>
                </section>

        </body>
</html>

login/index.php

$error = false;
if($_POST) {

        if($_POST['username'] == 'test' && $_POST['password'] == 'test') {
                //login successful
                setcookie('ampid', $_POST['ampid'], time()+3600);

                header('location:' + $_POST['redirect']);
                exit();
        }
        $error = true;
}

if(!isset($_REQUEST['rid'])) {
?>
        <script type="text/javascript">
                window.close();
        </script>
<?php
}

echo ($error ? "<h2>Invalid Credentials</h2>" : "");
?>

<h3>Login Form</h3>

<form method="post" action="/login">

        <label for="username">Username</label><br>
        <input type="text" value="test" name="username"><hr>

        <label for="password">Password</label><br>
        <input type="password" value="test" name="password"><hr>

        <input type="hidden" value="<?= $_REQUEST['ref']; ?>" name="redirect">
        <input type="hidden" value="<?= $_REQUEST['rid']; ?>" name="ampid">

        <input type="submit">Login</input>

</form>

logout/index.php

Currently empty.

login/index.php

header('AMP-Access-Control-Allow-Source-Origin: https://yoursite.com');
header('Content-type: application/json');

echo json_encode(
        array(
                'success'=>true,
                'access'=>true,
                'error'=>false
        )
);

The above code validates, no CORS error, and when you click the 'Login' link on the first page (index.html), it opens the login window, similar to the example.

When logging in, it validates, but I do not see a cookie being set ampid, and I am unable to force index.html to reload.

After manually reloading index.html the previous login, appears to have no effect.

If you look at the source for auth/index.php you will also note I am always sending back the equivalent of "Yes, you are logged in" json data.

What am I overlooking and how can I get this to work with my own authentication system (without using OAuth or similar external hosted credential services.). I have supplied a very basic example of an authentication system, so getting AMP to do it's magic with this, would be fantastic.

Kraang Prime
  • 9,981
  • 10
  • 58
  • 124
  • 1
    As an editor of this site, I have published a functional demonstration on how this can be done here : https://www.onezeroless.com/google-amp-and-amp-access-over-rest/ . Thank you Scriptonomy for your help. – Kraang Prime Oct 11 '17 at 08:42
  • A quick check of the onezeroless example and while I see the login popup when I submit there is no indication that the login was successfull - should the main page change? – Peter Scott Jun 03 '19 at 10:15
  • @PeterScott The code is functional, however the demo is not working because the login popup is being redirected to the same domain as that which does the login request. If you look at the code and then look at the URL, you will notice the slight - but very important change that is happening. – Kraang Prime Jun 04 '19 at 01:56

1 Answers1

3

Your code is mostly sound. However, there are a couple of issues:

  1. In your Auth code you are not returning a subscriber: true
  2. You don't need to redirect or refresh for amp-access to update

In your index.html you are setting the amp-access test parameter to subscriber, yet you are not returning a value of true for the subscriber key. Technically the subscriber key can be any arbitrary name. However, in your case you have set it to subscriber.

amp-access automatically posts and retrieves authorization value pairs when login or logout window is closed. Therefore, there is no need for a redirect or page reload. amp-access also automatically sets a cookie with the rid on the client side which you can access and use in your server side code.

Scriptonomy
  • 3,975
  • 1
  • 15
  • 23
  • Yeah it's not simple, but glad you figured it out. – Scriptonomy Oct 11 '17 at 07:36
  • It's not so bad once it's figured out. In summary, the `auth` pingback acts as a checker for any session/cookies and returns back an 'AMP' friendly response with just the basics. Kinda sucks to require a popup window for login/logout that I need to close after (and ensure the cookie/session had time to write first). – Kraang Prime Oct 11 '17 at 07:52