首先,进入Cognito Identity提供程序(在Cognito控制台中),并确保您的提供程序“授权范围”适合使用。例如,如果您点击了Google提供程序,则授权范围可能为“profile email openid”。授权范围将因提供程序而异,但无论使用什么范围,它必须提供访问用户电子邮件的权限。
当您的用户使用外部身份提供程序(比如Facebook)登录时,Cognito会与Facebook协商,然后调用您在Cognito控制台的“应用客户端设置”部分设置的回调URL。该回调包含一个称为“code”的参数 - 该参数在由Cognito进行的回调的URL中设置。该代码是OAuth令牌。
现在您在客户端中有了OAuth令牌,就需要将其POST到
AWS Token Endpoint。令牌终结点返回响应中的
三个新令牌:JWT ID令牌、JWT访问令牌和刷新令牌。从终结点响应中获取“id_token”属性。将其解析为json字符串,并取出其中的“email”元素。现在您应该有用户的电子邮件地址。
这是我的Java工作示例。这是一个由Cognito Callback调用的servlet。
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper;
import com.nimbusds.jwt.SignedJWT;
import net.minidev.json.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.URL;
import java.net.URLConnection;
public class CognitoLandingServlet extends HttpServlet {
static final Logger LOG = LoggerFactory.getLogger(CognitoLandingServlet.class);
private static final long serialVersionUID = 1L;
public CognitoLandingServlet() {
super();
}
@Override
protected void doGet(final HttpServletRequest request, final HttpServletResponse response)
throws ServletException, IOException {
final String code = request.getParameter("code");
LOG.debug(String.format("Cognito OAuth2 code received from Cognito: %s.", code));
if (code != null) {
} else {
LOG.debug(String.format(
"Landing page requested without a Cognito code, the request probably didn't come from Cognito"));
request.getRequestDispatcher("/signin").forward(request, response);
}
final String cognitoClientId = System.getProperty("CognitoClientId");
final String redirectUri = System.getProperty("CognitoCallBackUrl");
final String awsTokenEndpoint = System.getProperty("AwsTokenEndpoint");
final String jwt = swapOauthForJWT(cognitoClientId, code, redirectUri, awsTokenEndpoint);
loginWithJWT(jwt, request, response);
}
@Override
protected void doPost(final HttpServletRequest request, final HttpServletResponse response)
throws ServletException, IOException {
}
private void loginWithJWT(final String jwtString, final HttpServletRequest request,
final HttpServletResponse response) {
final JSONParser parser = new JSONParser();
SignedJWT signedIdJWT;
try {
final JSONObject json = (JSONObject) parser.parse(jwtString);
final String idToken = (String) json.get("id_token");
signedIdJWT = SignedJWT.parse(idToken);
final String userId = signedIdJWT.getJWTClaimsSet().getSubject();
final HttpSession session = request.getSession(true);
session.setAttribute("userId", userId);
final String cognitoUsername = (String) signedIdJWT.getJWTClaimsSet()
.getClaim("cognito:username");
if (cognitoUsername != null) {
user.setUserName(cognitoUsername);
session.setAttribute("username", cognitoUsername);
}
final String email = (String) signedIdJWT.getJWTClaimsSet().getClaim("email");
if (email != null) {
user.setEmail(email);
session.setAttribute("email", email);
}
response.sendRedirect("/dashboard");
LOG.info(
String.format("A user with userid %s and email %s successfully signed in", userId, email));
} catch (final java.text.ParseException e) {
LOG.error(
String.format("The JWT token could not be parsed by JOSE library. %s", e.getMessage()));
} catch (final ParseException e) {
LOG.error(String.format("The JWT token could not be parsed by JSON simple library. %s",
e.getMessage()));
} catch (final IOException e) {
LOG.error(String.format("Failed to request webpage at the end of the login process - io. %s",
e.getMessage()));
}
}
private String swapOauthForJWT(final String cognitoClientId, final String oauthCode,
final String redirectUri, final String awsTokenEndpoint) throws IOException {
final String urlParameters = String.format(
"Content-Type=application/x-www-form-urlencoded&grant_type=authorization_code&client_id=%s&code=%s&redirect_uri=%s",
cognitoClientId, oauthCode, redirectUri);
LOG.debug(String.format("User is swapping OAuth token for a JWT using URL %s", urlParameters));
final URL url = new URL(awsTokenEndpoint);
final URLConnection conn = url.openConnection();
conn.setDoOutput(true);
final OutputStreamWriter writer = new OutputStreamWriter(conn.getOutputStream());
writer.write(urlParameters);
writer.flush();
final BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
final StringBuilder responseStrBuilder = new StringBuilder();
String inputStr;
while ((inputStr = reader.readLine()) != null) {
responseStrBuilder.append(inputStr);
}
writer.close();
reader.close();
LOG.debug(String.format("Finished swapping OAuth token for a JWT"));
return responseStrBuilder.toString();
}
}