Security News
PyPI Introduces Digital Attestations to Strengthen Python Package Security
PyPI now supports digital attestations, enhancing security and trust by allowing package maintainers to verify the authenticity of Python packages.
@authx/http-proxy-web
Advanced tools
The AuthX proxy for clients is a flexible HTTP proxy designed to sit in front of a client and manage the entire OAuth flow.
The AuthX proxy for clients is a flexible HTTP proxy designed to sit in front of a client and manage the entire OAuth flow.
Example | Configuration | Development
Here is a typical use case:
We have a resource – often an API – which is accessed by a client. The route /something
is special, and we only want to give access to authorized users.
proxy = new AuthXClientProxy({
authxUrl: `htts://authx.example.com`,
// These need to match the values for your client in AuthX.
clientId: "3ac01e62-faba-4644-b4c0-7979775717ac",
clientSecret: "279b6f23893778b5edf981867a78a86d60c9bd3d",
clientUrl: "https://client.example.com",
// These are the scopes your client will request from users.
requestGrantedScopes: ["AuthX:user.equal.self:read.basic"],
rules: [
// We want the front-end to be able to access the AuthX API without managing
// credentials. To do this, we create a proxy that injects a token with all
// the necessary scopes and nothing more.
{
test({ method, url }) {
return method === "POST" && url === "/api/authx";
},
behavior(request) {
// Rewrite the URL to match the API's expectations.
request.url = "/graphql";
// Because this is an API request, we don't want to redirect the browser
// so we will return a 401 and include a `Location` header which the
// front-end can use to redirect the user.
return {
proxyOptions: { target: `https://authx.example.com` },
sendAuthorizationResponseAs: 401,
sendTokenToTargetWithScopes: ["authx.prod:**:**"],
};
},
},
// These are static assets that we want publically cached by Google Cloud
// CDN or Cloudflare. We won't require any auth for these endpoints.
{
test({ method, url }) {
return method === "GET" && /^\/static(\/.*)?$/.test(url || "");
},
behavior: {
proxyOptions: { target: `http://localhost:3001` },
},
},
// The rest of our routes render a single-page-app.
{
test() {
return true;
},
// These requests are likely made directly by the user, so we can simply
// redirect the user if we require more granted priviliges. Additionally,
// we don't need to generate a token for this target, so we can leave off
// `sendTokenToTargetWithScopes`. However, we still do want to ensure that
// the user is authenticated and has granted us scopes that are necessary
// for the app to work, so we will set `requireGrantedScopes`.
behavior: {
proxyOptions: { target: `http://localhost:3000` },
sendAuthorizationResponseAs: 303,
sendTokenToTargetWithScopes: [],
},
},
],
});
The proxy is configured with an array of rules, which are checked in order against the request URL until a match is found. If no match is found, the proxy will respond with a status of 404
.
interface Config {
/**
* The root URL to AuthX server.
*/
readonly authxUrl: string;
/**
* The ID assigned to this client by AuthX.
*/
readonly clientId: string;
/**
* A secret assigned to this client by AuthX.
*/
readonly clientSecret: string;
/**
* The URL at which the proxy will provide the OAuth client functionality.
*/
readonly clientUrl: string;
/**
* The scopes to request from the user.
*/
readonly requestGrantedScopes: string[];
/**
* The pathname at which the proxy will provide a readiness check.
*
* @remarks
* Requests to this path will return a 200 with the body "READY" when the
* proxy is ready to accept incoming connections, and a 503 with the body
* "NOT READY" otherwise.
*
* When closing the proxy, readiness checks will immediately begin failing,
* even before the proxy stops accepting requests.
*
* If unspecified, the path `/_ready` will be used.
*/
readonly readinessEndpoint?: string;
/**
* When the proxy injects a token into a request, it makes sure that the token
* will remain valid for this amount of time in seconds; otherwise it will
* request a new token from AuthX to use.
*
* If unspecified, 30 seconds will be used.
*/
readonly tokenMinimumRemainingLife?: number;
/**
* The rules the proxy will use to handle a request.
*/
readonly rules: Rule[];
}
interface Rule {
/**
* Each rule is tested in order, with the first to return `true` used to
* handle the request. This function MUST NOT manipulate the `request` object.
*/
readonly test: (request: IncomingMessage) => boolean;
/**
* The behavior to use for a matching request.
*
* @remarks
* If the request must be modified, such as to change the URL path, a custom
* function can be used here. This function will be called _after_ the
* `X-OAuth-Scopes` headers have been set or removed.
*
* If the function handles the request (such as returning an error), it must
* return `undefined` to prevent the proxy from also attempting to handle it;
* otherwise, it should return a `Behavior` config.
*/
readonly behavior:
| Behavior
| ((
request: IncomingMessage,
response: ServerResponse,
) => Behavior | undefined);
}
interface Behavior {
/**
* The options to pass to node-proxy.
*/
readonly proxyOptions: ServerOptions;
/**
* The HTTP status to use if the proxy requires authorization.
*
* @remarks
* 303 - This will return a 303 to redirect the browser to AuthX for
* authorization. After authorizing the proxy, the user will be returned to
* the requested page if the initial request was a GET request, or to the URL
* set in the referer header. Use this for endpoints with which a human user
* directly interacts.
*
* 401 - This will return a 401 with a `Location` header designating the AuthX
* URL to which the user should be directed for authorization. After
* authorizing the proxy, the user will be returned to the URL set in the
* referer header. Use this for endpoints with which a client-side app
* interacts using `fetch` or `XMLHttpRequest`.
*/
readonly sendAuthorizationResponseAs?: 303 | 401;
/**
* Pass a token to the target, restricting scopes to those provided.
*
* @remarks
* If unspecified, the proxy will forward the request to the target without a
* token, whether the user has authenticated the client or not. To only ensure
* the user is authenticated and has authorized the client in some capacity,
* use an empty array here.
*
* This is generally used to limit the token to the scopes needed by the
* request. For example, if we are authorized to:
*
* - lunch:apple:eat
* - recess:ball:throw
*
* ...and we want to send a token to the "cafeteria" resource that _only_ has
* access to "lunch" resources, we can limit it with: [ "lunch:**:**" ]
*/
readonly sendTokenToTargetWithScopes?: string[];
}
format
Use prettier to format the code in this package.
lint
Check the contents of this package against prettier and eslint rules.
prepare
Build the files from /src
to the /dist
directory with optimizations.
prepare:development
Build the files from /src
to the /dist
directory, and re-build as changes are made to source files.
test
Run all tests from the /dist
directory.
test:development
Run all tests from the /dist
directory, and re-run a test when it changes.
This holds the source code for the proxy.
The compiled and bundled code ends up here for distribution. This is ignored by git.
FAQs
The AuthX proxy for clients is a flexible HTTP proxy designed to sit in front of a client and manage the entire OAuth flow.
We found that @authx/http-proxy-web demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 2 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
PyPI now supports digital attestations, enhancing security and trust by allowing package maintainers to verify the authenticity of Python packages.
Security News
GitHub removed 27 malicious pull requests attempting to inject harmful code across multiple open source repositories, in another round of low-effort attacks.
Security News
RubyGems.org has added a new "maintainer" role that allows for publishing new versions of gems. This new permission type is aimed at improving security for gem owners and the service overall.