# Requesting an Access token with clientAppId and clientAppSecret

**URL:** <https://forum.solidproject.org/t/requesting-an-access-token-with-clientappid-and-clientappsecret/6042>\
**Category:** General Discussion\
**Created:** [January 12, 2023, 1:41pm UTC](https://forum.solidproject.org/t/requesting-an-access-token-with-clientappid-and-clientappsecret/6042 "2023-01-12T13:41:55Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![fandroide](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.solidproject.org/fandroide/32/3574_2.png) [@fandroide](https://forum.solidproject.org/u/fandroide)\
**Post date:** [January 12, 2023, 1:41pm UTC](https://forum.solidproject.org/t/requesting-an-access-token-with-clientappid-and-clientappsecret/6042/1 "2023-01-12T13:41:55Z")

</div>

Hi,

I have a question related to the process of requesting a token described in this article:  
[Automating authentication with Client Credentials](https://communitysolidserver.github.io/CommunitySolidServer/5.x/usage/client-credentials/#requesting-an-access-token).

If I follow the steps described above I can successfully get a DPoP token to make an authenticated request, but it looks like it’s mandatory to start by the following “login” request:

```auto
const response = await fetch('http://localhost:3000/idp/credentials/', {
  method: 'POST',
  headers: { 'content-type': 'application/json' },
  body: JSON.stringify({ email: 'my-email@example.com', password: 'my-account-password', name: 'my-token' }),
});

const { id, secret } = await response.json();

```

If I try to do a user-like login, as described in [https://solidproject.org/developers/tutorials/first-app:](https://solidproject.org/developers/tutorials/first-app:)

```auto
await session.login({
       oidcIssuer: SOLID_IDENTITY_PROVIDER,
       clientName: "Inrupt tutorial client app",
       redirectUrl: window.location.href
     });

```

and from the `session` object I try to use the `clientAppId` and `clientAppSecret` values:

```auto
let id 
let secret 
if (session.info.isLoggedIn) {            
     const sessionInfo = await session.clientAuthentication.getSessionInfo(session.info.sessionId)    
     console.log(sessionInfo)        
     id = sessionInfo.clientAppId
     secret = sessionInfo.clientAppSecret
} 

```

which looks like this:

```auto
{
    "sessionId": "83cc23b7-2ead-4aca-a54b-3be8a6dc2f2d",
    "webId": "http://localhost:3000/fandroide/profile/card#me",
    "isLoggedIn": true,
    "redirectUrl": "http://localhost:1234/index.html?state=d7d19dd52b0542b8909d89d139fdbdca",
    "issuer": "http://localhost:3000/",
    "clientAppId": "hqbqNjaxZ93o5yQuzUfk6",
    "clientAppSecret": "m2UoPL8_RJLUfdKJoNUAXyryZwxcu7KBM3E3SVLhKB6BX4GbIYQtKhPjstCsmvwym1nUBDShYzo9k6iL4pmHMQ",
    "tokenType": "DPoP"
}

```

then in the reply I will get a 401 Unauthorized error.

Is this error expected even being the same issuer and user though a different authentication request? Is there any way to get a token, in an automated way, without losing the flow of a user manual login?

Thanks in advance for your time and support!

---

<div class="post-metadata">

**Author:** ![ThisIsMissEm](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.solidproject.org/thisismissem/32/3166_2.png) [@ThisIsMissEm](https://forum.solidproject.org/u/ThisIsMissEm)\
**Post date:** [January 13, 2023, 2:20am UTC](https://forum.solidproject.org/t/requesting-an-access-token-with-clientappid-and-clientappsecret/6042/2 "2023-01-13T02:20:22Z")

</div>

I’ll have to remember to follow up here, but the summary I think is: client credentials are designed only for use on CLIs / maybe on servers, not on browser based apps. I think our docs on [https://docs.inrupt.com](https://docs.inrupt.com) might explain this better in the getting started guide.

---

<div class="post-metadata">

**Author:** ![fandroide](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.solidproject.org/fandroide/32/3574_2.png) [@fandroide](https://forum.solidproject.org/u/fandroide)\
**Post date:** [January 13, 2023, 10:34am UTC](https://forum.solidproject.org/t/requesting-an-access-token-with-clientappid-and-clientappsecret/6042/3 "2023-01-13T10:34:49Z")

</div>

Thanks for your reply @ThisIsMissEm !  
I’ve checked the documentation but unfortunately I can’t find a clear reference to this topic, only this:  
[Authenticate (Node.js: Single-User App) - Authenticate with Statically Registered Client Credentials](https://docs.inrupt.com/developer-tools/javascript/client-libraries/tutorial/authenticate-nodejs-script/#static-registration-of-a-client-application)  
I assume that `clientAppId` and `clientAppSecret` can’t be used to request a token as described in [Client credentials - Community Solid Server](https://communitysolidserver.github.io/CommunitySolidServer/5.x/usage/client-credentials/#requesting-an-access-token).

Another question related to this issue, but I’m not sure if I should better create a new topic for it, is regarding the endpoint:

```auto
http://localhost:3000/idp/credentials/

```

It seems it’s not available by default in all SOLID servers [IDP configuration](https://github.com/CommunitySolidServer/CommunitySolidServer/blob/9a5fc674f3f98c1d33122f5cde8a501449db6c1f/documentation/markdown/usage/identity-provider.md)

For example, if I try to reach:

```auto
https://solidcommunity.net/idp/credentials/

```

I get **`403 (Forbidden)`** error. Or in the case of Inrupt:

```auto
https://login.inrupt.com/idp/credentials/

```

It directly throws:

```auto
{
    "error": "invalid_request",
    "error_description": "404 Not Found"
}

```

So my general question is how can I be sure that I will get a valid token independent of the provider/issuer in order to request not public resources on behalf of a client/user?

I will try to summarize all the problems I’ve faced which are related with the topic [Music Platform](https://forum.solidproject.org/t/music-platform/5878) and having a middleware server to interact with a SOLID Pod, but first I need to gather all existing related topics and information.

---

<div class="post-metadata">

**Author:** ![ThisIsMissEm](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.solidproject.org/thisismissem/32/3166_2.png) [@ThisIsMissEm](https://forum.solidproject.org/u/ThisIsMissEm)\
**Post date:** [January 13, 2023, 8:54pm UTC](https://forum.solidproject.org/t/requesting-an-access-token-with-clientappid-and-clientappsecret/6042/4 "2023-01-13T20:54:30Z")

</div>

Yes, they can, you’ll want to follow: [Authenticate (Node.js: Single-User App) — Inrupt JavaScript Client Libraries](https://docs.inrupt.com/developer-tools/javascript/client-libraries/tutorial/authenticate-nodejs-script/#static-registration-of-a-client-application)

Specifically:

```auto
await session.login({
       oidcIssuer: SOLID_IDENTITY_PROVIDER,
       clientId: id,
       clientSecret: secret
});

```

If you pass just `clientName` and `redirectUrl`, then we do [Dynamic Client Registration](https://openid.net/specs/openid-connect-registration-1_0.html), if you just pass a `clientId` and that is a URL, then we treat it as doing [Solid OIDC via Client Identifier Document](https://solidproject.org/TR/oidc#clientids-document), if you pass both `clientId` and `clientSecret` (node.js only) then we treat it as “static” client credentials (essentially a pre-registered client).

**Edit:** I also want to point out that whilst you might be able to access `session.clientAuthentication`, this is actually a private API, and not part of our supported public API; You can see this in our code here: [solid-client-authn-js/Session.ts at main · inrupt/solid-client-authn-js · GitHub](https://github.com/inrupt/solid-client-authn-js/blob/main/packages/node/src/Session.ts#L94)

The Inrupt SDKs deliberately do not expose the credentials to the client, they’re kept in an in-memory closure, and deliberately not accessible outside of the SDK code, we only provide a `session.fetch` that applies the credentials to a [`fetch`](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) operation (in node.js this is currently powered by the `cross-fetch` package, but this is an implementation detail and changing soon-ish.

---

<div class="post-metadata">

**Author:** ![fandroide](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.solidproject.org/fandroide/32/3574_2.png) [@fandroide](https://forum.solidproject.org/u/fandroide)\
**Post date:** [January 16, 2023, 4:55pm UTC](https://forum.solidproject.org/t/requesting-an-access-token-with-clientappid-and-clientappsecret/6042/5 "2023-01-16T16:55:13Z")

</div>

Thank you so much for your reply, @ThisIsMissEm!

Now it’s clear for me that I should not use `session.clientAuthentication` to retrieve `clientAppId` and `clientAppSecret` after the user is logged in, but then my question is, **how can I get that info from the user (id and secret) in the browser or it’s simply not possible?**

On the other hand, I’ve been able to make the code below work in a separate `node.js` instance:

```auto
await session.login({
       oidcIssuer: SOLID_IDENTITY_PROVIDER,
       clientId: id,
       clientSecret: secret
});

```

The only problem is that it only works when I use the _ **client Id** _ and _ **secret** _ from the following screen (Inrupt’s server):

 ![inrupt_bot_app copy](https://europe1.discourse-cdn.com/flex017/uploads/solidproject/original/2X/e/ec0f311094f026c74defd45c1cb78f16b4f17ac2.png)

which means that I need to access [https://login.inrupt.com/registration.html](https://login.inrupt.com/registration.html) and manually register my app there. This is also a concern because it’s not an option for any SOLID server, only those which allow this feature, if I understand it correctly and eventually it can grant the app access to resources of users who have info in an Inrupt Pod but not “[solidcommunity.net](http://solidcommunity.net)”, for example, or my own public Community Solid Server instance.

In summary to briefly describe my goal and not complicate things, I’ll try to explain the objective of the topic and the way I thought it would be possible to achieve.

I have a SOLID web app and a user that logs in within the app using its SOLID issuer account. After a valid authentication it has some credentials (client ID, secret, token, whatever…) that can be sent to a middleware server in order to act on behalf of this user. The middleware server can use `clientId` and `clientSecret` for example to get a token and from there interact with the SOLID Pod.

Here you can find also a diagram and the related inspiration from the original [Music Platform thread](https://forum.solidproject.org/t/music-platform/5878/17)

 ![diagram_arch_first_approach](https://europe1.discourse-cdn.com/flex017/uploads/solidproject/original/2X/8/8313f8d3ae843e5c7e0cae3d9d22910ca33364f9.png)

Maybe there’s a better approach to the described problem. I can think of the existing thread: [Third-party resource verifying a session token](https://forum.solidproject.org/t/third-party-resource-verifying-a-session-token/5567) to find similar references.

So, if I’m not wrong, it should be possible to run an API call about a user’s piece of information in a `node.js` app, including `clientId` and `clientSecret`, like the described at:

> **[solid-client-authn-js/packages/node/examples/bootstrappedApp at main ·...](https://github.com/inrupt/solid-client-authn-js/tree/main/packages/node/examples/bootstrappedApp)**
>
> main/packages/node/examples/bootstrappedApp

```auto
node dist/authenticatedScript.js --clientId <the client id> --clientSecret <the client secret> --oidcIssuer <the issuer that issued the token> --resource <the private resource you want to access>

```

Thanks in advance and sorry for the verbose 😛

---

<div class="post-metadata">

**Author:** ![ThisIsMissEm](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.solidproject.org/thisismissem/32/3166_2.png) [@ThisIsMissEm](https://forum.solidproject.org/u/ThisIsMissEm)\
**Post date:** [January 16, 2023, 10:17pm UTC](https://forum.solidproject.org/t/requesting-an-access-token-with-clientappid-and-clientappsecret/6042/6 "2023-01-16T22:17:39Z")

</div>

That is not a credential flow we support — sharing credentials between client and server like this isn’t secure, you’d instead need to do two authentication flows, one for the client, and one for the server-side, if you really need server-side processing.

We explicitly don’t expose the credentials or DPoP token to the user, as to limit the ability for something to exfiltrate those credentials from the page within the browser.

---

<div class="post-metadata">

**Author:** ![ThisIsMissEm](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.solidproject.org/thisismissem/32/3166_2.png) [@ThisIsMissEm](https://forum.solidproject.org/u/ThisIsMissEm)\
**Post date:** [January 16, 2023, 10:19pm UTC](https://forum.solidproject.org/t/requesting-an-access-token-with-clientappid-and-clientappsecret/6042/7 "2023-01-16T22:19:42Z")

</div>

Another option is to have your server component have it’s own WebID and to grant that WebID access to specific parts of the pod, such that the server acts as it’s own agent & not on behalf of the user

---

<div class="post-metadata">

**Author:** ![Vincent](https://avatars.discourse-cdn.com/v4/letter/v/e9bcb4/32.png) [@Vincent](https://forum.solidproject.org/u/Vincent)\
**Post date:** [January 17, 2023, 8:09am UTC](https://forum.solidproject.org/t/requesting-an-access-token-with-clientappid-and-clientappsecret/6042/8 "2023-01-17T08:09:02Z")

</div>

Wouldn’t a possible flow be to _only_ do auth on the server, and have the server mediate all Pod interactions? (i.e. removing the line between “Web App” and “Solid Server” in the above diagram?)

---

<div class="post-metadata">

**Author:** ![ThisIsMissEm](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.solidproject.org/thisismissem/32/3166_2.png) [@ThisIsMissEm](https://forum.solidproject.org/u/ThisIsMissEm)\
**Post date:** [January 17, 2023, 11:39am UTC](https://forum.solidproject.org/t/requesting-an-access-token-with-clientappid-and-clientappsecret/6042/9 "2023-01-17T11:39:45Z")

</div>

You can indeed do completely server-rendered apps, if you so choose; but then your client is completely locked to your server working & being up.

---

<div class="post-metadata">

**Author:** ![fandroide](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.solidproject.org/fandroide/32/3574_2.png) [@fandroide](https://forum.solidproject.org/u/fandroide)\
**Post date:** [January 17, 2023, 3:14pm UTC](https://forum.solidproject.org/t/requesting-an-access-token-with-clientappid-and-clientappsecret/6042/10 "2023-01-17T15:14:20Z")

</div>

Thanks @Vincent and @ThisIsMissEm for your input 🙂

I’ll try to recap and propose a different approach based on the architecture that was mentioned in the [Music Platform thread](https://forum.solidproject.org/t/music-platform/5878/17), which means the web app needs a centralized/common server where it can grab all the info about people registered sharing resources. With a decentralized network as SOLID aims, it is required to find solutions, as far as I’ve learnt, so services like YouTube, Spotify, etc can be built, otherwise there’s no way for the users to exchange assets among them without previously knowing each other, correct me if I’m wrong, please.

**OPTION 1**  
The following animation describes the process of authentication with a SOLID server and shows how the web app is relying on a third party custom service to perform actions on behalf of the authenticated user. The Common Server can track all interactions made by the users because it’s responsible for them.

![option-1](https://europe1.discourse-cdn.com/flex017/uploads/solidproject/original/2X/a/a50e2a5f6c67d1c69b1cd192d611dda09e970201.gif)

**OPTION 2**

On the other hand, as an alternative (see animation below) , the web app is talking directly to the SOLID server and notifying the Common Server about the interactions afterwards. The only issue or concern I see in this approach, is **how can the Common Server verify when it’s notified by the client that the action was actually made by it ? (Steps 7 and 8 of the animation)**.

![option-2](https://europe1.discourse-cdn.com/flex017/uploads/solidproject/original/2X/6/6775790f6408515f83b895af1553105cb067308c.gif)

In summary, to make possible **Option 1** :

1. 

> _“need to do two authentication flows, one for the client, and one for the server-side”_ @ThisIsMissEm

How can I do authentication of a specific user in the server after the user is authenticated in the browser? I’m not sure if it refers to creating a request for the client so it passes {issuer, user and password (encrypted)} and then handling login in the server. Or maybe something like this, @ThisIsMissEm ? =\>[Authenticate (Node.js Web Server)](https://docs.inrupt.com/developer-tools/javascript/client-libraries/tutorial/authenticate-nodejs-web-server/#example)  
Is it what you mentioned with your comment [“You can indeed do completely server-rendered apps”](https://forum.solidproject.org/t/requesting-an-access-token-with-cliantappid-and-clientappsecret/6042/9) ?

1. 

> _“server component have it’s own WebID and to grant that WebID access to specific parts of the pod, such that the server acts as it’s own agent & not on behalf of the user”_ @ThisIsMissEm

I’m not aware of this possibility, sorry. I’d need to dig into it a bit more.

1. 

> _" to only do auth on the server, and have the server mediate all Pod interactions"_ @Vincent

How can you do auth only in the server @Vincent and still track clients interactions in a trusty way?

---

<div class="post-metadata">

**Author:** ![ThisIsMissEm](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.solidproject.org/thisismissem/32/3166_2.png) [@ThisIsMissEm](https://forum.solidproject.org/u/ThisIsMissEm)\
**Post date:** [January 17, 2023, 4:18pm UTC](https://forum.solidproject.org/t/requesting-an-access-token-with-clientappid-and-clientappsecret/6042/11 "2023-01-17T16:18:56Z")

</div>

> [@fandroide](#):
>
> How can I do authentication of a specific user in the server after the user is authenticated in the browser? I’m not sure if it refers to creating a request for the client so it passes {issuer, user and password (encrypted)} and then handling login in the server. Or maybe something like this, @ThisIsMissEm ? =\>[Authenticate (Node.js Web Server)](https://docs.inrupt.com/developer-tools/javascript/client-libraries/tutorial/authenticate-nodejs-web-server/#example)  
> Is it what you mentioned with your comment [“You can indeed do completely server-rendered apps”](https://forum.solidproject.org/t/requesting-an-access-token-with-cliantappid-and-clientappsecret/6042/9) ?

No, these are separate, you can just do authentication & data access through your own proprietary server, this does mean the client & server are strictly coupled, and that the server acts as the mediator to the data (i.e., the server acts on behalf of the user), and the client doesn’t directly interact with the pod. Some may deem this “less in the spirit of Solid”, but it is a design path that can be taken.

With OIDC, if you want the server-side to maintain the users’ session, typically, you’ll have the client create a session with the server (via session cookie) and then the server would redirect the client to start an OIDC flow, the server would then handle the return redirect, store the exchange the code for an access token / ID token & refresh token, which it stores securely (treat these as highly sensitive information: they are equivalent to passwords) in a database. Then all operations that the user wishes to do against the solid storage must go through your server to the resource server.

E.g.,

```auto
client (browser) <-> application server <-> authorization server 
                                            & resource server

```

This does make your client (browser) unable to directly interact with Solid resources in an authenticated context, and you’re essentially building an application against a REST API (that your application server provides).

The documentation at [Authenticate (Node.js Web Server) — Inrupt JavaScript Client Libraries](https://docs.inrupt.com/developer-tools/javascript/client-libraries/tutorial/authenticate-nodejs-web-server/#example) does explain it, but keep in mind that you’ll need to implement database-backed session storage (we only do in-memory out of the box), here is the interface you’ll need to conform to for that: [https://github.com/inrupt/solid-client-authn-js/blob/main/packages/core/src/storage/IStorage.ts](https://github.com/inrupt/solid-client-authn-js/blob/main/packages/core/src/storage/IStorage.ts) and you then pass it into the session code as the second argument to the various methods that work with sessions, e.g.,

```auto
// in memory:
const session = await getSessionFromStorage(req.session.sessionId);

// in database:
const session = await getSessionFromStorage(
  req.session.sessionId,
  myDatabaseBackedSessionStorage
);

```

* * *

There is also an alternative which is where the server acts on behalf of **itself** and has it’s own WebID and provisions it’s own JWT, which can then be used to interact with the pod as the servers’ WebID, and then the client interacts with their pod directly, but adds the servers’ WebID to the ACP/ACR/WAC permissions to allow the server to interact with resources using it’s WebID.

This is a pattern I’ve seen, but it is not widely documented, but is technically possible (the [ESS Query Service](https://docs.inrupt.com/ess/latest/services/service-query/#access-control) actually does this).

---

<div class="post-metadata">

**Author:** ![fandroide](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.solidproject.org/fandroide/32/3574_2.png) [@fandroide](https://forum.solidproject.org/u/fandroide)\
**Post date:** [January 17, 2023, 4:30pm UTC](https://forum.solidproject.org/t/requesting-an-access-token-with-clientappid-and-clientappsecret/6042/12 "2023-01-17T16:30:50Z")

</div>

OK, I think I get the point, thanks again for your great support @ThisIsMissEm! It looks like I have some homework for this week 😜
