Closed gadhagod closed 3 years ago
If one was able to use the same token to keep getting data from the server, it poses a big security risk. If anyone were to get hands on that token, they would be able to constantly get data from the application. The only way to make more tokens would be to use the username and password. The best way to constantly get access to information would be to store the username and password in a secure place (password vaults) and then whenever the token expires, use these in order to get a new token.
But when using 3-legged authentication I don't get the user's username and password.
You'll definitely want to store the token, not a username and password. Tokens are meant for maintenance of long-term connections that can be revoked or manipulated. Storing user credentials would be quite dangerous.
That said, it's been a while since I created this project, and I didn't implement 3-legged auth, so I'm not totally sure how to answer your question. @AndrewLester may have an answer as he was the one that added 3-legged auth.
If you'd like to reuse a user's authentication state after a session ends, you'll need to save their access_token
and access_token_secret
. When I implemented three-legged oauth, I didn't make it obvious how to do this. You can access the variables that hold their tokens, once they've been authorized, from the Auth
instance, which is available from the main Schoology
instance under schoology_auth
.
Then, you can apply these tokens to a newly created Auth
instance through the access_token
and access_token_secret
parameters on the constructor.
Replacing the current structure of the Auth
class with something like Authlib would be a good thing to do.
Thanks @AndrewLester. Will try this tonight.
I tried this code by putting the tokens into the auth. However, the new auth created using the token and token_secret has the wrong user.
import schoolopy
from os import getenv
from flask import Flask, redirect
auth = schoolopy.Auth(getenv('SCHOOLOGY_KEY'), getenv('SCHOOLOGY_SECRET'), three_legged=True, domain='https://schoology.harker.org/')
url = auth.request_authorization(callback_url="localhost"+'/authorized')
app=Flask(__name__)
@app.route("/login")
def login():
return redirect(url)
@app.route("/authorized")
def authorized():
print(auth.authorize())
tok=auth.access_token
sec=auth.access_token_secret
auth2 = schoolopy.Auth(getenv('SCHOOLOGY_KEY'), getenv('SCHOOLOGY_SECRET'), three_legged=False, domain='https://schoology.harker.org/', request_token=tok, request_token_secret=sec)
print(auth2.authorize())
sc=schoolopy.Schoology(auth)
sc2=schoolopy.Schoology(auth2)
print(sc.get_me().username)
#user1
print(sc2.get_me().username)
#owner of api
return(".")
app.run(host="0.0.0.0",port=80)
Shouldn't the sc.get_me().username
be same as the sc2.get_me().username
?
auth2 = schoolopy.Auth(getenv('SCHOOLOGY_KEY'), getenv('SCHOOLOGY_SECRET'), three_legged=False, domain='https://schoology.harker.org/', request_token=tok, request_token_secret=sec)
Try using the access_token
and access_token_secret
keyword arguments instead of request_token
and request_token_secret
here.
Other than that, your code looks good.
Edit: You actually don't even have to call authorize()
on the auth2
instance.
Edit 2: Also, you'll want to set three_legged
to True on the auth2
instance because it's still using the three_legged oauth protocol. Ok thats all the edits I think, sorry about that.
The following didn't work either: I set three_legged to True and changed request_token to access_token and request_token_secret to access_token_secret.
import schoolopy
from os import getenv
from flask import Flask, redirect
auth = schoolopy.Auth(getenv('SCHOOLOGY_KEY'), getenv('SCHOOLOGY_SECRET'), three_legged=True, domain='https://schoology.harker.org/')
url = auth.request_authorization(callback_url="localhost"+'/authorized')
app=Flask(__name__)
@app.route("/login")
def login():
return redirect(url)
@app.route("/authorized")
def authorized():
auth.authorize()
tok=auth.access_token
sec=auth.access_token_secret
auth2 = schoolopy.Auth(getenv('SCHOOLOGY_KEY'), getenv('SCHOOLOGY_SECRET'), three_legged=True, domain='https://schoology.harker.org/', access_token=tok, access_token_secret=sec)
sc=schoolopy.Schoology(auth)
sc2=schoolopy.Schoology(auth2)
print(sc.get_me().username)
#user1
print(sc2.get_me().username)
#owner of api
return(".")
app.run(host="0.0.0.0",port=80)
I still get the owner of the api for sc2.
That is understandable. I probably should have tested my solution before sending it.
Here's my updated solution:
auth2 = schoolopy.Auth(getenv('SCHOOLOGY_KEY'), getenv('SCHOOLOGY_SECRET'), three_legged=True, domain='https://schoology.harker.org/', access_token=tok, access_token_secret=sec)
auth2.oauth.token = {'oauth_token': tok, 'oauth_token_secret': sec}
Just add that second line. In all honesty, this is pretty much just a hack to bypass the jankyness of the Auth
class.
For the future of three-legged OAuth in schoolopy, I think using another OAuth library like Authlib
inside the Auth
class would be more beneficial, as requests-oauthlib
definitely isn't the most intuitive.
Thank you so much, this solution fixed the problem. Here is the final code incase anyone else wants to reference it:
import schoolopy
from os import getenv
from flask import Flask, redirect
auth = schoolopy.Auth(getenv('SCHOOLOGY_KEY'), getenv('SCHOOLOGY_SECRET'), three_legged=True, domain='https://schoology.harker.org/')
url = auth.request_authorization(callback_url="localhost"+'/authorized')
app=Flask(__name__)
@app.route("/login")
def login():
return redirect(url)
@app.route("/authorized")
def authorized():
auth.authorize()
tok=auth.access_token
sec=auth.access_token_secret
auth2 = schoolopy.Auth(getenv('SCHOOLOGY_KEY'), getenv('SCHOOLOGY_SECRET'), three_legged=True, domain='https://schoology.harker.org/', access_token=tok, access_token_secret=sec)
auth2.oauth.token = {'oauth_token': tok, 'oauth_token_secret': sec}
sc=schoolopy.Schoology(auth)
sc2=schoolopy.Schoology(auth2)
print(sc.get_me().username)
#user1
print(sc2.get_me().username)
#same as user 1
return(".")
app.run(host="0.0.0.0",port=80)
Yup. We got it working. Thanks @AndrewLester.
Hello. Once a user logs in using 3-legged, I get to see their Schoology stuff, like in the three-legged example. Cool.
However, is there a way to access their data even after the session is over? According to the docs:
But how can I re-access their data from schoolopy? Using the
Auth
command? What should I store in a database? Please let me know if I need to clarify this issue. Thanks.