Skip to content

Commit

Permalink
feat(#14): query status by ticket
Browse files Browse the repository at this point in the history
  • Loading branch information
Jeff-Tian committed Sep 7, 2023
1 parent 2505446 commit 3b36359
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 17 deletions.
6 changes: 3 additions & 3 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-services-social-weixin</artifactId>
<version>0.5.1</version>
<version>0.5.2</version>
<name>Keycloak Services Social WeiXin</name>
<description/>
<properties>
Expand All @@ -28,8 +28,8 @@
<version>3.11.0</version>
<configuration>
<encoding>UTF-8</encoding>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
<source>15</source>
<target>15</target>
</configuration>
</plugin>
<plugin>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,12 @@ protected UriBuilder createAuthorizationUrl(AuthenticationRequest request) {
var ticket = wechatApi.createTmpQrCode(new TicketRequest(2592000, "QR_STR_SCENE", new ActionInfo(new Scene("1")))).ticket;
logger.info("ticket = " + ticket);

uriBuilder.queryParam("ticket", ticket).queryParam("qr-code-url", "https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=" + ticket);
uriBuilder
.queryParam("ticket", ticket)
.queryParam(OAUTH2_PARAMETER_STATE, request.getState().getEncoded())
.queryParam(OAUTH2_PARAMETER_REDIRECT_URI, request.getRedirectUri())
.queryParam("qr-code-url", "https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=" + ticket)
;
}
} else {
uriBuilder = UriBuilder.fromUri(config.getAuthorizationUrl());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
import java.util.Map;
import java.util.Objects;

import static org.keycloak.broker.oidc.AbstractOAuth2IdentityProvider.OAUTH2_PARAMETER_REDIRECT_URI;

public class QrCodeResourceProvider implements RealmResourceProvider {
private final KeycloakSession session;
protected static final Logger logger = Logger.getLogger(QrCodeResourceProvider.class);
Expand Down Expand Up @@ -48,20 +50,45 @@ public Response helloAnonymous() {
@GET
@Path("mp-qr")
@Produces(MediaType.TEXT_HTML)
public Response mpQrUrl(@QueryParam("ticket") String ticket, @QueryParam("qr-code-url") String qrCodeUrl) {
public Response mpQrUrl(@QueryParam("ticket") String ticket, @QueryParam("qr-code-url") String qrCodeUrl, @QueryParam("state") String state, @QueryParam(OAUTH2_PARAMETER_REDIRECT_URI) String redirectUri) {
logger.info("展示一个 HTML 页面,该页面使用 React 展示一个组件,它调用一个后端 API,得到一个带参二维码 URL,并将该 URL 作为 img 的 src 属性值");

String htmlContent = "<!DOCTYPE html>\n" +
"<html>\n" +
"<head>\n" +
" <title>QR Code Page</title>\n" +
"</head>\n" +
"<body>\n" +
" <div id=\"qrCodeContainer\">\n" +
" <img src=\"" + qrCodeUrl + "\" alt=\"" + ticket + "\">\n" +
" </div>\n" +
"</body>\n" +
"</html>";
var template = """
<!DOCTYPE html>
<html>
<head>
<title>QR Code Page</title>
</head>
<body>
<p>请使用微信扫描下方二维码:</p>
<div id="qrCodeContainer">
<img src="%s" alt="%s">
</div>
<script type="text/javascript">
async function fetchQrScanStatus() {
const res = await fetch(`mp-qr-scan-status?ticket=${%s}`, {
headers: {
'Content-Type': 'application/json'
}
})
const {status, openid} = await res.json()
if (openid) {
window.location.href = `%s?openid=${openid}&state=${%s}`
} else {
setTimeout(fetchQrScanStatus, 1000)
}
}
fetchQrScanStatus()
</script>
</body>
</html>
""";

String htmlContent = String.format(template, qrCodeUrl, ticket, ticket, redirectUri, state);

// 返回包含HTML内容的响应
return Response.ok(htmlContent, MediaType.TEXT_HTML_TYPE).build();
Expand All @@ -83,6 +110,8 @@ public Response mpQrScanStatus(@QueryParam("ticket") String ticket) {
var expireSeconds = ticketEntity.getExpireSeconds();
var ticketCreatedAt = ticketEntity.getTicketCreatedAt();
var status = ticketEntity.getStatus();
var openid = ticketEntity.getOpenid();
var scannedAt = ticketEntity.getScannedAt();

if ((Long) expireSeconds < System.currentTimeMillis() / 1000 - (Long) ticketCreatedAt) {
status = "expired";
Expand All @@ -92,7 +121,14 @@ public Response mpQrScanStatus(@QueryParam("ticket") String ticket) {
}

logger.info(String.format("ticket is %s%n, status is %s%n", ticket, status));
return Response.ok(Map.of("ticket", ticket, "expireSeconds", expireSeconds, "ticketCreatedAt", ticketCreatedAt, "status", status)).build();
return Response.ok(Map.of(
"ticket", ticket,
"expireSeconds", expireSeconds,
"ticketCreatedAt", ticketCreatedAt,
"status", status,
"openid", openid,
"scannedAt", scannedAt
)).build();
}

@SneakyThrows
Expand Down

0 comments on commit 3b36359

Please sign in to comment.