Skip to content

Commit 07a3359

Browse files
author
Markus-Malkusch
committed
Use Login V3
1 parent c7f6dfc commit 07a3359

File tree

3 files changed

+39
-16
lines changed

3 files changed

+39
-16
lines changed

pom.xml

+5-5
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,11 @@
2626
<artifactId>jackson-databind</artifactId>
2727
<version>2.18.3</version>
2828
</dependency>
29-
<dependency>
30-
<groupId>com.auth0</groupId>
31-
<artifactId>java-jwt</artifactId>
32-
<version>4.5.0</version>
33-
</dependency>
29+
<dependency>
30+
<groupId>com.fasterxml.jackson.datatype</groupId>
31+
<artifactId>jackson-datatype-jsr310</artifactId>
32+
<version>2.18.3</version>
33+
</dependency>
3434
<dependency>
3535
<groupId>dev.failsafe</groupId>
3636
<artifactId>failsafe</artifactId>

src/main/java/de/malkusch/niu/Authentication.java

+32-10
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,47 @@
11
package de.malkusch.niu;
22

3-
import static java.util.Objects.requireNonNull;
43

54
import java.io.IOException;
5+
import java.math.BigInteger;
6+
import java.security.MessageDigest;
7+
import java.security.NoSuchAlgorithmException;
68
import java.time.Duration;
79
import java.time.Instant;
810

9-
import com.auth0.jwt.JWT;
11+
import static java.nio.charset.StandardCharsets.UTF_8;
12+
import static java.util.Objects.requireNonNull;
1013

1114
final class Authentication {
1215

1316
private final String account;
1417
private final String password;
1518
private final String countryCode;
1619
private final Client client;
20+
private final static String APP_ID = "niu_8xt1afu6";
1721

1822
public Authentication(String account, String password, String countryCode, Duration expirationWindow, Client client)
1923
throws IOException {
2024

2125
this.account = assertNotEmpty(account, "account must not be empty");
22-
this.password = assertNotEmpty(password, "password must not be empty");
26+
this.password = hashedPassword(assertNotEmpty(password, "password must not be empty"));
2327
this.countryCode = assertNotEmpty(countryCode, "countryCode must not be empty");
2428
this.expirationWindow = requireNonNull(expirationWindow);
2529
this.client = requireNonNull(client);
2630

2731
refreshToken();
2832
}
2933

34+
private static String hashedPassword(String password) {
35+
try {
36+
var md5 = MessageDigest.getInstance("MD5");
37+
md5.update(UTF_8.encode(password));
38+
return String.format("%032x", new BigInteger(1, md5.digest()));
39+
40+
} catch (NoSuchAlgorithmException e) {
41+
throw new IllegalStateException(e);
42+
}
43+
}
44+
3045
private static String assertNotEmpty(String value, String errorMessage) {
3146
requireNonNull(value);
3247
if (value.isEmpty()) {
@@ -51,29 +66,36 @@ public Token token() throws IOException {
5166
}
5267

5368
private final Duration expirationWindow;
54-
private static final String LOGIN_URI = "https://account-fk.niu.com/appv2/login";
69+
private static final String LOGIN_URI = "https://account-fk.niu.com/v3/api/oauth2/token";
5570
private static Duration EXPIRES_AT_FALLBACK = Duration.ofHours(1);
5671

5772
private void refreshToken() throws IOException {
5873

74+
// Todo Use refresh token
75+
5976
record Response(Data data, String desc, int status) {
60-
record Data(String token) {
77+
record Data(Token token) {
78+
record Token(String access_token, Instant token_expires_in) {
79+
}
6180
}
6281
}
63-
var response = client.post(Response.class, LOGIN_URI, new Field("countryCode", countryCode),
64-
new Field("account", account), new Field("password", password));
82+
var response = client.post(Response.class, LOGIN_URI,
83+
new Field("countryCode", countryCode),
84+
new Field("app_id", APP_ID),
85+
new Field("grant_type", "password"),
86+
new Field("account", account),
87+
new Field("password", password));
6588

6689
if (response.status != 0) {
6790
throw new IOException(String.format("Can't authenticate: [%d] %s", response.status, response.desc));
6891
}
6992

70-
var token = response.data.token;
93+
var token = response.data.token.access_token;
7194

7295
Instant expiresAt;
7396
try {
74-
var jwt = JWT.decode(token);
7597
var now = Instant.now();
76-
expiresAt = jwt.getExpiresAtAsInstant();
98+
expiresAt = response.data.token.token_expires_in;
7799
if (expiresAt == null) {
78100
expiresAt = now.plus(EXPIRES_AT_FALLBACK);
79101
}

src/main/java/de/malkusch/niu/Client.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import com.fasterxml.jackson.core.JacksonException;
1818
import com.fasterxml.jackson.databind.ObjectMapper;
1919

20+
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
2021
import de.malkusch.niu.Authentication.Token;
2122

2223
record Field(String name, String value) {
@@ -59,7 +60,7 @@ public Client(Duration timeout, Retry<String> retry, String userAgent) {
5960
throw new IllegalArgumentException("userAgent must not be empty");
6061
}
6162

62-
mapper = new ObjectMapper();
63+
mapper = new ObjectMapper().registerModule(new JavaTimeModule());
6364
mapper.configure(FAIL_ON_UNKNOWN_PROPERTIES, false);
6465
}
6566

0 commit comments

Comments
 (0)