Closed JeepNL closed 1 year ago
Could it be because there's no scope defined here (ConnectWithCode
):
[edit]
See the Mastodon API docs here (obtain the token, grant_type=authorization_code
needs a scope?) :
https://docs.joinmastodon.org/client/authorized/#token
And here:
https://docs.joinmastodon.org/methods/oauth/#token
scope
String. List of requested OAuth scopes, separated by spaces (or by pluses, if using query parameters). If code was provided, then this must be equal to the scope requested from the user. Otherwise, it must be a subset of scopes declared during app registration. If not provided, defaults to read.
Well, that's (Scope) not it.
When I do this (without scope) in an Ubuntu environment
curl -X POST \
-F 'client_id=[REDACTED] \
-F 'client_secret=[REDACTED] \
-F 'redirect_uri=https://localhost/auth/return' \
-F 'grant_type=authorization_code' \
-F 'code=[REDACTED]' \
https://mastodon.social/oauth/token
I'm getting the AccessToken
.
{"access_token":"[REDACTED]","token_type":"Bearer","scope":"read write follow","created_at":1675610689}
But (still) not when I call Auth? auth = await authClient.ConnectWithCode(userAuth.Code);
in my Web API.
Maybe what is missing is the redirect_uri
Did you register the app with a redirect_uri provided ? if so, maybe you need to use the same when connecting with code. You provided it on your curl test
When calling ConnectWithCode, the redirect_uri is an optional argument :
Auth? auth = await authClient.ConnectWithCode(userAuth.Code, "https://localhost/auth/return");
Sorry, just tried that, and it gives the same error.
I did register the app with that same (and now only 1) url. Maybe it's URL Encoding somewhere? I don't know, I'm just guessing.
Not sure what is going on, everything seems ok
You can try to use WebUtility.UrlEncode
π€·ββοΈ
Did you follow the docs ? https://github.com/glacasa/Mastonet/blob/main/DOC.md
Maybe check the sample code to see if there are differences ? https://github.com/glacasa/Mastonet.SampleApp/blob/master/Mastonet.SampleApp/Login.xaml.cs
Yes, I've read the docs (DOC.md) and followed it. I'll need to read the sample maybe more carefully :)
I've created a temporary GitHub Repo with my project here (all of the code, work in progress)
That project should run out of the box locally (localhost) I think. De (SQLite) DB is provided, but empty. To test you should enter the Mastodon Instance you use to login.
Note: when the app redirects you in your browser to your instance for authentication, the first time maybe you'll see an error. If you use F5 (refresh browser) the remote auth page will show correctly. The URL (in the brower) is correct, I don't know yet why this is happening ...
'Hourra' π
I've got the access token!
I've changed a couple of things, I need to check what exactly made it work but I think it was the CORS definition in Program.cs
I'm not 100% sure, I've to check it tomorrow because my head is dizzy ...
using Api.Tusk.Data;
using Microsoft.EntityFrameworkCore;
var builder = WebApplication.CreateBuilder(args);
builder.Host.UseSystemd();
// Add services to the container.
string? connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
builder.Services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlite(connectionString!));
string[] origins = builder.Configuration["Origins"]!.Split(";");
builder.Services.AddCors(options =>
{
options.AddPolicy("ApiPolicy", builder =>
{
builder.WithOrigins(origins)
.SetIsOriginAllowedToAllowWildcardSubdomains()
.AllowCredentials()
.AllowAnyMethod()
.AllowAnyHeader()
.WithExposedHeaders("*");
});
});
builder.Services.AddHsts(options =>
{
options.Preload = true;
options.IncludeSubDomains = true;
options.MaxAge = TimeSpan.FromDays(365);
});
builder.Services.AddControllers();
var app = builder.Build();
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseCors("ApiPolicy");
app.MapControllers().RequireCors("ApiPolicy");
app.MapGet("/", () => "Error #1");
app.MapGet("/Error", () => "Error #2");
app.Run();
FYI:
I've encountered several problems with my code and with the remote Mastodon instance (mastodon.social) but it has little to do with your library Mastonet (except when you've a multiline RedirectUri
, more about that later).
Many times my mastodon instance, mastodon.social, returned "invalid_grant", but if I retried it with the same code
, the instance returned the AccessToken
So, now I've implemented a 'retry', with 3.33 seconds delay, in my code, and it works somewhat better.
***** authClient.AppRegistration.Id: 1863056
***** authClient.AppRegistration.Instance: mastodon.social
***** authClient.AppRegistration.Scope: Read, Write, Follow
***** authClient.AppRegistration.RedirectUri: https://localhost/auth/return
***** authClient.AppRegistration.ClientId: [REDACTED]
***** authClient.AppRegistration.ClientSecret: [REDACTED]
***** (AccessToken) TRY: 1
***** (AccessToken) ERROR: 1 - RETRY
***** Exception Mastonet.ServerErrorException: invalid_grant
at Mastonet.BaseHttpClient.TryDeserialize[T](String json)
at Mastonet.BaseHttpClient.Post[T](String route, IEnumerable`1 data, IEnumerable`1 media)
at Api.Tusk.Controllers.MastoAuthController.AccessToken(UserAuth userAuth) in C:\X\Repos\Tusk\ApiTusk\Controllers\MastoAuthController.cs:line 61
***** (AccessToken) TRY: 2
***** (AccessToken) ERROR: 2 - RETRY
***** Exception Mastonet.ServerErrorException: invalid_grant
at Mastonet.BaseHttpClient.TryDeserialize[T](String json)
at Mastonet.BaseHttpClient.Post[T](String route, IEnumerable`1 data, IEnumerable`1 media)
at Api.Tusk.Controllers.MastoAuthController.AccessToken(UserAuth userAuth) in C:\X\Repos\Tusk\ApiTusk\Controllers\MastoAuthController.cs:line 61
***** (AccessToken) TRY: 3
info: Microsoft.AspNetCore.Mvc.Infrastructure.ObjectResultExecutor[1]
Executing OkObjectResult, writing value of type 'System.String'.
info: Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker[105]
Executed action Api.Tusk.Controllers.MastoAuthController.AccessToken (Api.Tusk) in 6903.3197ms
info: Microsoft.AspNetCore.Routing.EndpointMiddleware[1]
Executed endpoint 'Api.Tusk.Controllers.MastoAuthController.AccessToken (Api.Tusk)'
info: Microsoft.AspNetCore.Hosting.Diagnostics[2]
Request finished HTTP/2 POST https://localhost:8081/Api/MastoAuth/AccessToken application/json;+charset=utf-8 83 - 200 - text/plain;+charset=utf-8 6903.6726ms
Info
(update)
Mastonet version: 2.2.1 .NET SDK: 7.0.200-preview.22628.1 Instance: mastodon.social Project: Front-end Blazor WASM with back-end Web API
Problem
I'm getting a Mastonet.ServerErrorException: invalid_grant at the Web API backend
Auth? auth = await authClient.ConnectWithCode(userAuth.Code);
when I try to get theAccessToken
and I do not know what I'm doing wrong.This is the last step in my WebAPI to receive the user's Access Token, right after the user has authorized Mastodon to use my app (see Image 1)
I saved the
AppRegistration
in a database, and I initializeAuthenticationClient
with that info. Every field is filled with the (I think) correct value π (update)Part of Web API Controller
UserAuth.cs
Error Dev Console (Response)
Error Web API Console
Image 1