sso method
- PortalServiceCode serviceCode
Performs single sign-on (SSO) to authenticate with a target NTUT service.
This method must be called after login to obtain session cookies for other NTUT services (Course Service, Score Service, or I-School Plus).
The SSO process:
- Fetches an SSO form from Portal with the service code
- Submits the form to the target service
- Sets the necessary authentication cookies for that service
All services share the same cookie jar, so SSO only needs to be called once per service during a session.
Throws an Exception if the SSO form is not found (user may not be logged in).
Implementation
Future<void> sso(PortalServiceCode serviceCode) async {
// Fetch a self-submitting SSO form
final response = await _portalDio.get(
'ssoIndex.do',
queryParameters: {'apOu': serviceCode.code},
);
// Parse the HTML to extract the form
final document = parse(response.data);
final form = document.querySelector('form[name="ssoForm"]');
if (form == null) {
throw Exception('SSO form not found. Are you logged in?');
}
// Extract form action and inputs
final actionUrl = form.attributes['action']!;
final inputs = form.querySelectorAll('input');
final formData = <String, dynamic>{
for (final input in inputs)
if (input.attributes['name'] != null)
input.attributes['name']!: input.attributes['value'] ?? '',
};
// Prepend the invalid cookie filter interceptor for i-School Plus SSO
if (serviceCode == PortalServiceCode.iSchoolPlusService) {
_portalDio.interceptors.insert(0, InvalidCookieFilter());
_portalDio.transformer = PlainTextTransformer();
}
// Submit the SSO form and follow redirects
// Sets the necessary cookies for the target service
await _portalDio.post(
actionUrl,
data: formData,
options: Options(contentType: Headers.formUrlEncodedContentType),
);
}