How do I authorise an app (web or installed) without user intervention?

前端 未结 2 1603
温柔的废话
温柔的废话 2020-11-21 04:39

Let\'s say that I have a web app that needs to access Drive files in a background service. It will either own the files it is accessing, or be run in a Google Account with w

2条回答
  •  情深已故
    2020-11-21 05:00

    Let me add an alternative route to pinoyyid's excellent answer (which didn't work for me - popping redirect errors).

    Instead of using the OAuthPlayground you can also use the HTTP REST API directly. So the difference to pinoyyid's answer is that we'll do things locally. Follow steps 1-3 from pinoyyid's answer. I'll quote them:

    1. Create the Google Account (eg. my.drive.app@gmail.com) - Or skip this step if you are using an existing account.
    2. Use the API console to register the mydriveapp (https://console.developers.google.com/apis/credentials/oauthclient?project=mydriveapp or just https://console.developers.google.com/apis/)
    3. Create a new set of credentials (NB OAuth Client ID not Service Account Key and then choose "Web Application" from the selection)

    Now, instead of the playground, add the following to your credentials:

    Authorized JavaScript Sources: http://localhost (I don't know if this is required but just do it.)
    Authorized Redirect URIs: http://localhost:8080

    Screenshot (in German):

    Make sure to actually save your changes via the blue button below!

    Now you'll probably want to use a GUI to build your HTTP requests. I used Insomnia but you can go with Postman or plain cURL. I recommend Insomnia for it allows you to go through the consent screens easily.

    Build a new GET request with the following parameters:

    URL: https://accounts.google.com/o/oauth2/v2/auth
    Query Param: redirect_uri=http://localhost:8080
    Query Param: prompt=consent
    Query Param: response_type=code
    Query Param: client_id=
    Query Param: scope=
    Query Param: access_type=offline
    

    If your tool of choice doesn't handle URL encoding automagically make sure to get it right yourself.

    Before you fire your request set up a webserver to listen on http://localhost:8080. If you have node and npm installed run npm i express, then create an index.js:

    var express = require('express');
    var app = express();
    
    app.get('/', function (req, res) {
      res.send('ok');
      console.log(req)
    });
    
    app.listen(8080, function () {
      console.log('Listening on port 8080!');
    });
    

    And run the server via node index.js. I recommend to either not log the whole req object or to run node index.js | less for the full output will be huge.
    There are very simple solutions for other languages, too. E.g. use PHP's built in web server on 8080 php -S localhost:8080.

    Now fire your request (in Insomnia) and you should be prompted with the login:

    Log in with your email and password and confirm the consent screen (should contain your chosen scopes).

    Go back to your terminal and check the output. If you logged the whole thing scroll down (e.g. pgdown in less) until you see a line with code=4/....

    Copy that code; it is your authorization code that you'll want to exchange for an access and refresh token. Don't copy too much - if there's an ampersand & do not copy it or anything after. & delimits query parameters. We just want the code.

    Now set up a HTTP POST request pointing to https://www.googleapis.com/oauth2/v4/token as form URL encoded. In Insomnia you can just click that - in other tools you might have to set the header yourself to Content-Type: application/x-www-form-urlencoded.

    Add the following parameters:

    code=
    client_id=
    client_secret=
    redirect_uri=http://localhost:8080
    grant_type=authorization_code
    

    Again, make sure that the encoding is correct.

    Fire your request and check the output from your server. In the response you should see a JSON object:

    {
      "access_token": "xxxx",
      "expires_in": 3600,
      "refresh_token": "1/xxxx",
      "scope": "https://www.googleapis.com/auth/drive.file",
      "token_type": "Bearer"
    }
    

    You can use the access_token right away but it'll only be valid for one hour. Note the refresh token. This is the one you can always* exchange for a new access token.

    * You will have to repeat the procedure if the user changes his password, revokes access, is inactive for 6 months etc.

    Happy OAuthing!

提交回复
热议问题