Skip to content

WIP: fix: Add studio login check to ensure authenticated #2335

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

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 36 additions & 1 deletion src/index.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {
APP_INIT_ERROR, APP_READY, subscribe, initialize, mergeConfig, getConfig, getPath,
APP_INIT_ERROR, APP_READY, APP_AUTH_INITIALIZED, subscribe, initialize, mergeConfig, getConfig, getPath,
} from '@edx/frontend-platform';
import { getAuthenticatedHttpClient } from '@edx/frontend-platform/auth';
import { AppProvider, ErrorPage } from '@edx/frontend-platform/react';
import React, { StrictMode, useEffect } from 'react';
import { createRoot } from 'react-dom/client';
Expand Down Expand Up @@ -145,6 +146,40 @@
);
});

subscribe(APP_AUTH_INITIALIZED, async () => {
// Authoring also requires authenticated access to the Studio APIs.
// Some of these APIs also require a logged in Studio user,
// so we must ensure that's the case there.
// If there isn't a logged in Studio user, then we can redirect to the Studio login page.

const studioBaseUrl = getConfig().STUDIO_BASE_URL;
// hacky try/catch with xblock handler as a PoC
try {
const url = `${studioBaseUrl }/xblock/`;
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is anyone aware of an appropriate cms api endpoint we can call here to check if the user is logged in? It needs to be a readonly (get) request that will return something we can use to check - eg. a 403 if the user isn't logged in.

The /xblock/ endpoint is not good for this purpose, but it's used here in the PoC because it redirects to the login page and the request fails with the CORS error if we're not logged in, otherwise it will return something.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be reasonable to add such an api endpoint to the CMS if one doesn't already exist?

Or we may need to look at other methods, such as checking for a valid studio_session_id cookie locally(?).

Copy link
Contributor

@bradenmacdonald bradenmacdonald Jul 30, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Authentication is supposed to be abstracted away by frontend-platform so I'd look there for a relevant JS API method, or add one if it doesn't exist (checkAuthStatus() ?).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But also there's what I said on the other issue - a cookie should not be required for our MFEs. All APIs should accept a JWT token as auth, and it's easy to check if the JWT is expired or not. If a given API is not accepting a JWT, it should be fixed upstream or we should change to use a proper API endpoint. This would also solve the fake CORS errors, because proper API endpoints will not mask a 403 error with a CORS error.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd look there for a relevant JS API method, or add one if it doesn't exist (checkAuthStatus() ?).

I did check there, and found that it does have the method for this, which is called in the init phase if requireAuthenticatedUser is true. However, that appears to go through the LMS, and it uses the login_refresh endpoint to refresh the JWT. This endpoint does actually exist on the CMS - but if that's for setting the JWT, and if the JWT is shared between the LMS and CMS, and we should be updating the CMS APIs to use JWTs, then it shouldn't be needed at all. I think. I need to learn more about how auth is set up here. :)

await getAuthenticatedHttpClient().get(url, {
validateStatus: (status) => (status >= 200 && status <= 500),
});
// if response indicates not logged in
} catch {
console.log('STUDIO IS NOT LOGGED IN');

Check warning on line 164 in src/index.jsx

View workflow job for this annotation

GitHub Actions / tests

Unexpected console statement
// TODO: check for a redirect from the studio login page, to avoid infinite redirect loops
// code from upstream lms auth handler for reference:
// const isRedirectFromLoginPage = global.document.referrer
// && global.document.referrer.startsWith(this.config.LOGIN_URL);

// if (isRedirectFromLoginPage) {
// const redirectLoopError = new Error('Redirect from login page. Rejecting to avoid infinite redirect loop.');
// logFrontendAuthError(this.loggingService, redirectLoopError);
// throw redirectLoopError;
// }

console.log(`REDIRECTING TO: ${studioBaseUrl}/login?next=${encodeURIComponent(window.location.href)}`);

Check warning on line 176 in src/index.jsx

View workflow job for this annotation

GitHub Actions / tests

Unexpected console statement
global.location.assign(`${studioBaseUrl}/login?next=${encodeURIComponent(window.location.href)}`);
return;
}
console.log('STUDIO IS LOGGED IN');

Check warning on line 180 in src/index.jsx

View workflow job for this annotation

GitHub Actions / tests

Unexpected console statement
});

initialize({
handlers: {
config: () => {
Expand Down
Loading