API 2.0: How to Get OAuth Access Token Programmatically without SmugMug Login Form?

ckelleyckelley Registered Users Posts: 26 Big grins
How can I programmatically provide my SmugMug credentials (SmugMug userID and SmugMug password and/or API Key and API Key secret) to obtain an OAuth Access token and OAuth secret?

I need to know because our application currently authenticates hundreds of users that upload photos to a single SmugMug account via API 1.2.2. Our users are not required to login to SmugMug in order to do so. Our web server application authenticates itself programmatically when it creates an API 1.2.2 session to perform the upload. Requiring each user to login to SmugMug before returning to our application to upload photos is an API 2.0 migration showstopper.

Comments

  • gabbiegabbie Registered Users Posts: 66 Many Grins
    edited March 27, 2015
    We ended up talking more about ckelley's specific case via email, but for anyone else looking at this thread: there is no function that would accept SmugMug credentials and return OAuth. But the good news is that OAuth tokens don't expire (unless you manually de-authorize them through the SmugMug Account Settings), so once you get the token you're set. You can check out our API documentation to learn more about working with OAuth.
    gabbie
    SmugMug Product Manager
  • ckelleyckelley Registered Users Posts: 26 Big grins
    edited March 30, 2015
    Python Example Works Intermittantly
    SmugMug API 2.0 uses OAuth 1.0a for authentication and authorization. To migrate to API 2.0, I must perform the following steps:
    1. Get an OAuth Access Token and Secret from SmugMug’s OAuth server. Both the Access Token and Secret are strings that do not expire. So once we have it, it should support all our SmugMug upload requests. To get an Access Token and Secret, I need a program that will follow the flow described at http://www.cubrid.org/blog/dev-platform/dancing-with-oauth-understanding-how-authorization-works/:
      1. Obtain an unauthorized request token from SmugMug using our SmugMug API Key and API Secret.
      2. Use the unauthorized token to get an authorized request token using Noel’s SmugMug login credentials.
      3. Use the authorized request token to get an Access Token and secret.
    2. Replace our API 1.2.2 calls to SmugMug with API 2.0 methods having the Access Token and Secret stuffed into their request headers.
    I derived a program from https://code.google.com/p/devdefined-tools/wiki/OAuth to perform Step 1 above. But, I couldn't work around a "signature_invalid" error I encountered in Step 1a.

    So, I installed Python 3.4.3, rauth 0.7.1, bottle 0.12.8, copied the SmugMug sample code from https://api.smugmug.com/api/v2/doc/tutorial/oauth/web.html and tried running it under PyCharm Community Edition 4.0.5. I got a lot of 500 server errors with invalid SSL certificate while using Fiddler2 to monitor HTTPS communications. But, the errors disappeared after I killed Fiddler2. I was able to set a breakpoint at "set_cookie({'at': at, 'ats': ats})" and copy the access token (at) and its secret (ats) values out of the PyCharm debugger variable window.
  • ckelleyckelley Registered Users Posts: 26 Big grins
    edited March 31, 2015
    Where to Put OAuth Access Token and Secret in HTTP Requests?
    As of 31 Mar 2015, the API 2.0 Upload documentation states:

    "The Uploader API accepts the same OAuth access tokens as the main API. However, the Uploader only supports receiving the OAuth parameters in the Authorization header, not in the query string or request body."

    Then it presents a list of the Request Header properties. But, it does not include the names of the OAuth Access Token and Secret. What are the names of these essential properties?

    Are the OAuth header property names the same as defined Table 6. OAuth Parameters Required to Call Open APIs using the Access Token of Dancing with OAuth: Understanding How OAuth Works ? If so, Table 6 includes "oauth_token" for the token, but omits the secret. Is the secret not required?

    Will setting this same set of OAuth properties in the HTTP Request header work for all our requests to the API?
  • ktvoelkerktvoelker Registered Users Posts: 25 Big grins
    edited March 31, 2015
    The OAuth parameters are not sent as individual headers; they are all sent in a single header called Authorization. The format of this header is specified by the OAuth 1.0a standard: https://tools.ietf.org/html/rfc5849#section-3.5.1.
    Karl Voelker
    Sorcerer and API Guy at SmugMug
  • ckelleyckelley Registered Users Posts: 26 Big grins

    I need to repeat what I did in 2015 to obtain an OAuth Token and OAuth Token Secret for a new API Key and API Key Secret in 2023. You'd think it would be easy a second time, but it's not.

    Here's what I've done so far:

    1. Downloaded the Python app from https://gist.github.com/smugmug-api-docs/10046914.
    2. Installed Python 3.9
    3. Installed PyCharm 2022.3.2 (Community Edition)
    4. Opened the Python app in PyCharm
    5. Created a config.json file from example.json and plugged in my API Key and API Key Secret.
    6. "run-web.sh" to install all the dependencies.
    7. Added an Inbound Rule to my Windows 11 Windows Defender Firewall to allow inbound requests via port 8090.
    8. Set a breakpoint in web.py at "set_cookie({'at': at, 'ats': ats})" so that I can copy the access token (at) and its secret (ats) values out of the PyCharm debugger variable window before it writes them to a cookie.
    9. I ran it in debug mode.
    10. I got to launching the web server at "run(host=HOST, port=PORT)"
    11. I verified that it was running by accessing "http://localhost:8090" in my web browser. The page has a single [Authorize] anchor on it that invokes the /authorize route.
    12. Then nada. SmugMug never calls back. How do I isolate the problem?
  • ckelleyckelley Registered Users Posts: 26 Big grins
    edited March 6, 2023

    According to the SmugMug API 2.0 documentation at https://api.smugmug.com/api/v2/doc/tutorial/authorization.html , you can use the sample Python app at https://api.smugmug.com/api/v2/doc/tutorial/oauth/web.html or https://gist.github.com/smugmug-api-docs/10046914 to obtain the necessary OAuth Token and Token Secret. This worked for me 7 years ago. But, times have changed. This app depends on bottle.py 0.12.8 which requires Python 3.5 or earlier. The app also requires rauth.py 0.7.1 that requires Python 3.4 or earlier. Both Python 3.4 and 3.5 have reached end of life and no longer supported and http://Python.org/downloads no longer offers Windows installers for same. Looks like I am faced with trying to make an unsupported Python application work in order to regain access to the API that we have used to store over 1 million images on SmugMug.

    When I tried using Python 3.9, bottle.py 0.12.8 failed with a “TypeError: Missing required parameter 'digestmod'“ error that is typically raised when using an older version of the hmac module in Python 2.x that does not have the digestmod parameter. This parameter was added in Python 2.5.

    So, I upgraded the two library dependencies to rauth==0.7.3 and bottle==0.12.25 and got much further:

    1. localhost:8090 displayed an Authorize link like before.

    2. A request was sent to SmugMug that returned a request token and secret when was stored in a cookie named 'c'.

    3. Then I was redirected to http://secure.smugmug.com/login where I was able to login successfully.

    4. Clicking [LOG IN] resulted in SmugMug sending a request to my http://localhost:8090/callback site. My PyCharm debugger picked up the thread. Unfortunately, the Python program cannot read the cookie named 'c' that it wrote previously to recall the request token and request secret. The domain (localhost), path (/) and name (“c”) of the cookie appear to be correct, but bottle.request.get_cookie returns a None value when read before it can attempt to decrypt it.

    5. Switched from using MS Edge Version 110.0.1587.56 to Chrome Version 110.0.5481.178 and it worked. I captured the OAuth token and Secret by setting a breakpoint in PyCharm 2022.3.2 (Community Edition) at line 76 set_cookie({'at': at, 'ats': ats})

  • ckelleyckelley Registered Users Posts: 26 Big grins
    edited March 6, 2023

    According to the SmugMug API 2.0 documentation at https://api.smugmug.com/api/v2/doc/tutorial/authorization.html, you can use the sample Python app at https://api.smugmug.com/api/v2/doc/tutorial/oauth/web.html or https://gist.github.com/smugmug-api-docs/10046914 to obtain the necessary OAuth Token and Token Secret. This worked for me 7 years ago. But, times have changed. This app depends on bottle.py 0.12.8 which requires Python 3.5 or earlier. It also requires rauth.py 0.7.1 that requires Python 3.4 or earlier. Both Python 3.4 and 3.5 have reached end of life and no longer supported. Looks like I am faced with trying to make an unsupported Python application work in order to regain access to the API that we have used to store over 1 million images on SmugMug for my client, iD Tech. We develop on Windows 11 PCs and there is no longer a Windows install for Python 3.4 or 3.5.

    So I tried using Python 3.9 and upgraded the dependencies to rauth==0.7.3 and bottle==0.12.25. I restarted the app and got the Authorize page at http://localhost:8090. I clicked on the "Authorize" link and that redirected me to https://secure.smugmug.com/login. I logged in successfully and it send a request back to http://localhost:8090/callback. But, it failed to request the OAuth Token and Secret because it could not read the cookie that it wrote to save the request token and secret it received after I clicked Authorize. When it called bottle.py request.get_cookie('c') the value returned was None before it could even attempt to use the secret to decrypt it.

  • edcallahanedcallahan Registered Users Posts: 1 Beginner grinner
    edited December 3, 2023
    I was starting to follow @ckelley down the same wormhole, and this thread was really helpful. But then I realized two things that make this unnecessary for me. I'll drop those here in case it helps anyone else:

    1. You can access public data without obtaining any authorization. However, you must include your API key in every such request. Just add APIKey=your-key-here to the query string of each request URL. (https://api.smugmug.com/api/v2/doc/tutorial/api-key.html), So, for what I was doing, I didn't need an access token at all or mess with OAuth!

    2. You can get an access token directly from the smugmug Account Settings pages, in the Privacy section. So the python script isn't needed at all. I think, I didn't delve into it deeply because of #1 above.

    Hope that saves someone some time :)
Sign In or Register to comment.