|
| 1 | +.. _oauth: |
| 2 | + |
| 3 | +Using Tokens for Your Projects |
| 4 | +------------------------------ |
| 5 | + |
| 6 | +Let's say you're designing an application that uses github3.py. If your |
| 7 | +intention is to have users authenticate, you have a few options. |
| 8 | + |
| 9 | +1. Ask the user to enter their credentials each time they start the |
| 10 | + application. (Or save the username somewhere, and just ask for the |
| 11 | + password.) |
| 12 | +2. Ask the user to supply their credentials once and store them somewhere for |
| 13 | + later use. (**VERY VERY BAD**) |
| 14 | +3. Ask the user to supply their credentials once, get an authorization token |
| 15 | + and store that for later use. |
| 16 | + |
| 17 | +The first isn't a bad method at all, it just unfortunately may lead to unhappy |
| 18 | +users, this should always be an option though. The second (as I already noted) |
| 19 | +is a bad idea. Even if you obfuscate the username and password, they can still |
| 20 | +be discovered and no level of obfuscation is clever enough. (May I also take |
| 21 | +this moment to remind people that base64 is **not** encryption.) The last is |
| 22 | +probably the least objectionable of the evils. The token has scopes so there |
| 23 | +is only so much someone can do with it and it works well with github3.py. |
| 24 | + |
| 25 | +Requesting a token |
| 26 | +------------------ |
| 27 | + |
| 28 | +If you're not doing a web application, you are more than welcome to use |
| 29 | +github3.py (otherwise work with redirects_). Let's say your application needs |
| 30 | +access to public and private repositories, and the users but not to gists. |
| 31 | +Your scopes_ should be ``['user', 'repo']``. I'm also assuming your |
| 32 | +application will not be deleting any repositories. The only things left to do |
| 33 | +are collect the username and password and give a good description for your |
| 34 | +application. |
| 35 | + |
| 36 | +:: |
| 37 | + |
| 38 | + from github3 import authorize |
| 39 | + from getpass import getuser, getpass |
| 40 | + |
| 41 | + user = getuser() |
| 42 | + password = '' |
| 43 | + |
| 44 | + while not password: |
| 45 | + password = getpass('Password for {0}: '.format(user)) |
| 46 | + |
| 47 | + note = 'github3.py example app' |
| 48 | + note_url = 'http://example.com' |
| 49 | + scopes = ['user', 'repo'] |
| 50 | + |
| 51 | + auth = authorize(user, password, scopes, note, note_url) |
| 52 | + |
| 53 | + with open(CREDENTIALS_FILE, 'w') as fd: |
| 54 | + fd.write(auth.token + '\n') |
| 55 | + fd.write(auth.id) |
| 56 | + |
| 57 | +In the future, you can then read that token in without having to bother your |
| 58 | +user. If at some later point in the lifetime of your application you need more |
| 59 | +privileges, you simply do the following: |
| 60 | + |
| 61 | +:: |
| 62 | + |
| 63 | + from github3 import login |
| 64 | + |
| 65 | + token = id = '' |
| 66 | + with open(CREDENTIALS_FILE, 'r') as fd: |
| 67 | + token = fd.readline().strip() # Can't hurt to be paranoid |
| 68 | + id = fd.readline().strip() |
| 69 | + |
| 70 | + gh = login(token=token) |
| 71 | + auth = gh.authorization(id) |
| 72 | + auth.update(add_scopes=['repo:status', 'gist'], rm_scopes=['user']) |
| 73 | + |
| 74 | + # if you want to be really paranoid, you can then test: |
| 75 | + # token == auth.token |
| 76 | + # in case the update changes the token |
| 77 | + |
| 78 | +Hopefully this helps someone. |
| 79 | + |
| 80 | +.. _redirects: http://developer.github.com/v3/oauth/#redirect-urls |
| 81 | +.. _scopes: http://developer.github.com/v3/oauth/#scopes |
0 commit comments