Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OAuth-based authentication #147

Open
marioverhaeg opened this issue Aug 12, 2022 · 7 comments
Open

OAuth-based authentication #147

marioverhaeg opened this issue Aug 12, 2022 · 7 comments

Comments

@marioverhaeg
Copy link

Hi, I see this project is not updated for a while, but I'm a happy user :-). Are you planning to update it according to the latest Netatmo instructions regarding the OAuth authentication scheme described here? https://dev.netatmo.com/apidocumentation/oauth

If not, I will probably need to find an alternative or build something myself.

Thanks!

@Riges Riges mentioned this issue Aug 13, 2022
@aurnor
Copy link

aurnor commented Aug 30, 2022

Hello,

What I see from the new Netatmo authentication is that the Client Credentials grant type method will be completely removed on October 2022 (information also received by email).
This means that calls to client.GenerateToken("account", "password", scopes) won't work anymore.
My app has no user interaction, so without Client Credentials I won't be able to generate a CredentialToken anymore using OAuth.
However, in this Netatmo forums discussion, a Netatmo representative said:

"_Note that you are already supposed to use the client credential only once to generate then refresh & access token then use those tokens in your application every day use.
This means that if you already use the best practice method, the client credential change would not change anything for you except of course if you loose the token somehow or wish to add more scopes. In short you already have the access & refresh token required for your current use. On my personnal app I didn't need to do a client cred since 2~3 years and that was only because I added scopes.

We are naturally working on a better solution for new users such as allowing the refresh and access token generation directly from your dev account but that' still WIP and prone to change. To be clear you will still need to use the refresh method for automation if you do not want to redo the token every 3 hours.
Note that I personnaly recommend getting the new refresh token and access to automatically replace the previous ones with every refresh. It's not that complicated and you make sure to have the correct data everytime even in the evantuality that we would need to change stuff arround._
"

So I think one of the first steps is to set the CredentialManager.CredentialToken public (currently it is a private set), so that we can get a Token and refresh token from the developer portal manually (I'm still not sure how), then set it from our code directly into the CredentialToken property (from a config file for example).

@marioverhaeg
Copy link
Author

My application also doesn't have a user interface. I basically gather the data from Netatmo and write it into an InfluxDB database. I had the same issue with another cloud provider and used the log files as a "user interface". Meaning, if there is user interaction required I would write the URL into a log file, and execute the user interaction manually. As also said on the forums, once it runs you hardly ever need to do it again. It's not the nicest solution, but it works for my purposes :-).

@aurnor
Copy link

aurnor commented Aug 31, 2022

Yes, once we have a token and refresh token, it is supposed to be enough, provided that we can set them in the CredentialToken property, @Riges ;)
But the question is to know how we will get those tokens easily. From the Netatmo dev portal we can get an access token, but not the refresh token.
Perhaps the easiest way is to get the current token and refresh token we get using Client Credentials grant as long as it works, and use them directly in our code (storing them in a config file) and avoid the call to Client Credentials.
Or create a sample app that uses OAuth to get the tokens with user interaction, then inject them into our non-UI app.

@marioverhaeg
Copy link
Author

marioverhaeg commented Aug 31, 2022

This is what I received from the Netatmo API support team:

_In the future what you can do is setting up a server on your device hosting the code and access it via your smartphone or any display you would have. Your mobile phone has to be on the same network than the device hosting your code.

The device should then redirect the call directly to https://api.netatmo/com/oauth2/authorize?client_id=''&redirect_uri=''&scope='' and setting the redirect uri as the locale ip of your device 192.168.xx. It does not need to be accessible from the outside but only on your local network.

On the mobile phone, you'd then be redirected on Netatmo front and it will ask you whether you want to gave access to the API app. When you'll click on 'Yes, I accept', Netatmo servers will send the code to Netatmo frontend which will redirect it to the locale ip from the redirect uri. In the end https://192.168.x.x/?code='' will be received by the device hosting your development and will then be able to get the pair of tokens (access tokens& refresh token)._

This should require minimum user interaction. The only thing the user needs to do is kick-off the process by calling the API with a clientId. and redirect ID, and then login on the Netatmo portal. It would require a temporary HTTP server running, but that can be switched off once the authentication process is complete.

@aurnor
Copy link

aurnor commented Aug 31, 2022

My code already runs on a web server, so it may be a solution as well indeed. Asking user-interaction this way, only if refresh token was lost...
@Riges, any idea when you will implement oAuth authentication with user interaction in this project?
Thanks

@aurnor
Copy link

aurnor commented Sep 16, 2022

It seems that the Refresh Token given by Netatmo is always the same for my account.
So I could workaround the issue this way:

//If client does not exist, create it and ask for a token
if (client?.CredentialManager?.CredentialToken == null)
{
    client = new Netatmo.Client(NodaTime.SystemClock.Instance, baseUrl,
    configuration.GetValue<string>("NetatmoClientId"), configuration.GetValue<string>("NetatmoClientSecret"));

    
    //await client.GenerateToken(configuration.GetValue<string>("NetatmoAccount"), configuration.GetValue<string>("NetatmoPassword"), new[] { Scope.StationRead });

    //workaround here 
    var token = new Token();
    token.ExpiresIn = 10800;
    token.RefreshToken = configuration.GetValue<string>("NetatmoRefreshToken");
    var credentialToken = new Netatmo.Models.CredentialToken(token, NodaTime.SystemClock.Instance);
    //CredentialToken is read-only, using reflection to set it
    typeof(CredentialManager).GetProperty("CredentialToken").SetValue(client.CredentialManager, credentialToken, null);
}

if (client.CredentialManager.CredentialToken?.ExpiresAt.ToDateTimeUtc().ToLocalTime() < DateTime.Now
    || client.CredentialManager.CredentialToken?.AccessToken == null)
    await client.RefreshToken();

@marioverhaeg
Copy link
Author

It seems like the grant_type "password" has been disabled now all together (since yesterday?).

Riges added a commit that referenced this issue Aug 16, 2024
This PR is a simply convert to .Net 6 and update dependencies.
It should be fix issue #127

Next should be : use .Net 5 and 6 news features (likes records) + see
issue #147.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants