peeter123 / digikey-api

Python module for the Digikey PartSearch API
GNU General Public License v3.0
85 stars 35 forks source link

Token retreival not working when using the code in a server #16

Closed ParalaX002 closed 3 years ago

ParalaX002 commented 3 years ago

I'm trying to use the code in an application that runs on a server (inside a docker to be precise).

The problem is that I can't generate the token this way: indeed, the request is made to Digikey by the server, so the webpage of Digikey authorization never displays. I also tried changing the redirect URL to my server address, but same issue.

The only way to make this work is to generate the token on my machine, then upload the token on the server. However, the token has a very limited lifespan.

Looking at the Digikey API, there seems to be a "refresh" token that is valid 90 days, maybe that could do the job?

I also want to thank you for the code, as it helped me a lot :)

eeintech commented 3 years ago

@ParalaX002 The refresh token is included in the token_storage.json file. However if you use the same API access on a different machine, this refresh token will be updated and the server one will become obsolete, therefore require full authentication process to run again. Is that what's happening?

Also, not sure this library uses the "90 days" refresh token, where did you see this info on Digi-Key's developer website? Is there an option for shorter expiration?

ParalaX002 commented 3 years ago

@eeintech Thanks for your answer.

Indeed, I guess the problems come from the full identification that is necessary on the server. I don't really know how I could redirect the authentification page on my browser, then send the result to my server (I guess this is how it should work, but I never see the authentification page)

For the 90 days token, I saw it at the end of this page: https://developer.digikey.com/documentation/oauth

eeintech commented 3 years ago

Do you mean the "refresh" is blocked by your server? I rarely have to interact with the browser if I work of only one instance of the token, the API library handles it well. So my guess is that you have a problem with the refreshing step?

ParalaX002 commented 3 years ago

No, I mean that on the server I can never see the authorization page, which is the root of the issue. So I can't authenticate at all.

So what I do as a workaround is that I run the software on my PC, then authenticate, and send the token to the server. However, it doesn't work long (I have to measure how long it work). My guess, with what you said, is that because the PC is changed, then the refresh token is not working, and since the server can't display the authentification page, it fails. But it can be something else, I'm not sure at this point.

On my PC I indeed rarely see the authentification screen.

eeintech commented 3 years ago

Oh yes the initial authentication would need to be done elsewhere, right. I was referring only to the refresh.

I'm not sure how long the refresh token actually lives on. I do agree it's a little annoying to have to authenticate through the browser, wish Digi-Key provided a better way...

ParalaX002 commented 3 years ago

It won't be an issue to authenticate on the page if it was possible to do it with the code running on the server. Isn't there a way to display the authentification page on the browser of the user, even thought the application is running on the server? I tried changing the redirect URL, but the page never displays anyway so it's not working

My problem is that there is several users for my program, and they don't have the knowledge to regenerate a token, and upload it on the server every few days...

eeintech commented 3 years ago

I don't know about changing the URL sorry.

At our company, I ask each person to register for their own API instance, so that we all manage our own authentication locally. It does not take much time to do so and could maybe save you trouble? I documented this here: https://github.com/sparkmicro/Ki-nTree/#requirements

Another way to do this would be to wrap your API usage to run:

  1. Pull token file from server
  2. Do your API logic locally
  3. Push token file back to server for next person

I think concurrency works because whoever pushes back last has the most up-to-date token info, but I may be wrong.

ParalaX002 commented 3 years ago

Ok, thanks for your help.

Indeed maybe I can find a way to generate the token with a small program that someone uses and refresh the server automatically.

I'll come back here if I find something interesting :)

ParalaX002 commented 3 years ago

Hi,

So I managed to get a workaround: I bypassed the oauth2 authentification, by displaying the user the link to the digikey authentification window. That is, I display the link at line 255 of oauth2.py:

open_new(self.__build_authorization_url())

Doing so open the window in the user's browser. Then, I change also the redirection API to my server, so I can catch the DIGIKEY answer. From there, I copy pasted most of your code to obtain the token.

If the method in oauth2.py were easily accessible from the main api, all the copy-pasting of the code I did would be avoidable. An interface like this could work I think: DigiKey.auth_obtain_url (return the url that the user needs to enter) DigiKey.auth_handle_code (is fed with the digikey answer, and generate the post command to get the token) DigiKey.auth_check_token (indicate if the token is valid, so the user now when to initiate a new connection) Notice that in this scenario, I don't use the http server you are using, as my application is itself a web server that can handle the answers. But a function for launching it could be nice

Also, some more function to be able to set the redirection URL and port would be a good addition.

gregdingle commented 3 years ago

Hi, I'm looking into doing something similar, run the API client in a stateless cloud function, and so I have the same concern. It sounds like this approach should work me, after the initial browser auth is stored in the token file:

Another way to do this would be to wrap your API usage to run:

  1. Pull token file from server
  2. Do your API logic locally
  3. Push token file back to server for next person

I think concurrency works because whoever pushes back last has the most up-to-date token info, but I may be wrong.

I'd love any feedback on this approach for a cloud function. Thanks!

eeintech commented 3 years ago

@gregdingle I'm doing this for myself, so I always keep an up-to-date token in a private repo and use it across computers, it works quite well. I have scripts for automatically fetching and updating my local token file from the repo and push it back when done using. You can even use GitHub for that, if you set your repo as private.

eeintech commented 3 years ago

@ParalaX002 Any more feedback on this? Can this issue be closed?

ParalaX002 commented 3 years ago

Hi,

No more feedback, there is the workaround I posted, but if you implemented something, I didn't have the time to test it. For me, you can close the issue if you don't intend to provide such an interface.

Regards

eeintech commented 3 years ago

@ParalaX002 Thanks for providing the workaround. I'm not the maintainer of this repo so please close it :+1: