Skip to content
This repository has been archived by the owner on May 10, 2021. It is now read-only.

Create means to get raw JWT from uPort Connect queries #245

Open
MidnightLightning opened this issue Nov 27, 2018 · 1 comment
Open

Create means to get raw JWT from uPort Connect queries #245

MidnightLightning opened this issue Nov 27, 2018 · 1 comment

Comments

@MidnightLightning
Copy link
Contributor

When integrating with uPort to log users into a web application, traditional web applications track user sessions on the back-end, binding a session to a given user after the person at the keyboard has proved that's who they are (typically with username/password entry).

In doing the uPort disclosure request flow, the onResponse() method returns the properties (payload) from the message JWT already disassembled. That makes it easy for front-end code to just use the attributes from the JWT directly (trusting the Connect library already did the check to verify the signature on the JWT), but that cannot be used to initialize a user session securely:

/*** DON'T DO THIS!! ***/
uport.onResponse(reqID).then(rs => {
  const did = rs.payload.did;
  myWebAppAPI.startSessionForUser(did); // Use the DID to create a user session
});

This is a bad workflow, since then the DID has to be treated as a secret; if an attacker learns what the user's DID string is, they can manually create a user session for them (effectively logging in as them) outside of an onResponse call.

For a Web 3.0 app that doesn't have a traditional database back-end, the front-end UI can track "logged in" status and use browser local storage to track the DID of the user after they've gone through the uPort process, but to hand off the login flow to a back-end process, something to prove the user actually agreed to this login is needed.

The natural solution to that I believe is to give access to the Selective Disclosure Response JWT in full (including the signature). Then the front-end can give that to the back-end, and the back-end can use its own JWT library to verify the signature before trusting the DID inside it.

To give the option of getting the full JWT to all responses, I suggest adding it as a sendOpts option (e.g. includeJWT):

uport.send(requestJWT, queryID, {
  includeJWT: true
});
uport.onResponse(queryID).then(rs => {
  console.log(rs.jwt);
});

uport.requestDisclosure(
  { requested: ['name', 'email'] },
  queryID,
  { includeJWT: true }
);
uport.onResponse(queryID).then(rs => {
  myWebAppAPI.verifyAndStartSession(rs.jwt);
});
@PlakJakub
Copy link

What is the status of this issue? Will the proposed changes be implemented?

In our application I wanted to register / login using uport.

After clicking on the log in button :

  1. Client run server method.
  2. On server using createDisclosureRequest from 'uport-credentials' create requestToken.
import {Credentials} from 'uport-credentials';
...
const credentials = new Credentials({appName, address, signer}),
...
const requestToken = Promise.await(
  credentials.createDisclosureRequest({
    notifications: true,
    requested: ['name', 'country']
  })
);
  1. Return requestToken to client.
  2. The user with requestToken tries to get the jwt. But jwt can only be sent to the server directly via the uport
import {Connect} from 'uport-connect';
const uport = new Connect();
const reqID = "login"
...
uport.send(requestToken, reqID)
uport.onResponse(reqID).then(() => {
  ...
})
  1. If in the previous step on the client side I would get the jwt then I then run login method with jwt
Accounts.callLoginMethod(
  uport: true,
  jwt
});
  1. On the server side, I could verify the jwt and allow the user to log in.

Without getting the full JWT to the client, how else would we solve this issue?

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants