keycloak是一个开源的单点登录库,包括一整套前后端整体的开源库,最近一个德国客户自己搭建了keycloak服务器,需要在客户端做登录。其实我之前没用过keycloak,对这个东西很陌生,趁机研究了一把,文档还没有完全吃透,但是已经帮他解决了问题,这里先记录一下使用过程,后期如有类似项目或更深入项目可直接使用。由于我之前对keycloak一无所知,当用户把clientid、realm、以及authurl发我的时候我一脸懵逼,这个东西怎么用?于是我打算自己照着官网教程自己搭一下后台试试,这样测试就方便了……
keycloak官网
下载最新版本(目前是14):
官方快速开始教程:https://www.keycloak.org/getting-started/getting-started-zip
这里记录一下流程:
1、下载解压之后,进入
bin
目录下,(macos)执行:
./standalone.sh
2、等待服务器起来之后打开url:http://localhost:8080/auth,创建管理员账号,
3、登录管理员账号http://localhost:8080/auth/admin/master/console/
4、创建新得realm
这里我创建的是myrealm,记住名字很关键!!!
5、创建系统用户并设置密码:
image.png
image.png
我这里设置的是1317272927@qq.com/123456789
6、http://localhost:8080/auth/realms/myrealm/account/#/ 登录新创建的用户,进行测试。
这里服务器设置就完成了,好了我们进行app端的开发。
react-native keycloak
一开始我查了好多keycloak相关的库,基本都是通过打开系统浏览器的方式进行单点登录,我花了大约有7-8个小时进行了调研测试,最终这个库在如果需要打开浏览器的方式进行登录的话,能正常work:
https://github.com/react-keycloak/react-native-keycloak
它的用法如下:
const keycloak = new RNKeycloak({
url: "http://localhost:8080/auth",
realm: "myrealm",
clientId: "myclient"
});
<ReactNativeKeycloakProvider
authClient={keycloak}
onInitError={(event, error) => {
console.log("onKeycloakEvent", event, error);
}}
initOptions={{
redirectUri: "myapp://Homepage",
onLoad: "login-required",
// if you need to customize "react-native-inappbrowser-reborn" View you can use the following attribute
inAppBrowserOptions: {
// For iOS check: https://github.com/proyecto26/react-native-inappbrowser#ios-options
// For Android check: https://github.com/proyecto26/react-native-inappbrowser#android-options
},
}}
>
<Login />
</ReactNativeKeycloakProvider>
export default function StartScreen() {
const { keycloak } = useKeycloak();
const goLogin = useCallback(() => {
keycloak?.login();
}, []);
return (
<View style={tailwind("h-full pt-16 px-8 ")}>
<View style={tailwind("justify-center items-center h-1/4")}>
<Image
style={tailwind("w-14 h-14 ")}
resizeMode="contain"
source={require("../../assets/logo.png")}
/>
</View>
<Placeholder
Animation={Fade}
style={tailwind("h-1/2")}
// Left={PlaceholderMedia}
// Right={PlaceholderMedia}
>
<PlaceholderLine height={35} />
<View style={tailwind("justify-center items-center")}>
<Image
style={tailwind("w-1/3 mb-16 mt-8")}
source={require("../../assets/image-placeholder.jpg")}
/>
</View>
<PlaceholderLine height={25} />
<PlaceholderLine height={25} />
</Placeholder>
<View>
<View
style={tailwind("flex-row items-center justify-center -mt-8 mb-12")}
>
<Text style={tailwind("text-blue-400 text-2xl")}>←</Text>
<Text style={tailwind("text-blue-400 text-2xl ml-8")}>→</Text>
</View>
<Button mode="contained" uppercase={false} onPress={goLogin}>
Get started
</Button>
</View>
</View>
);
}
效果如下:
Jul-08-2021 23-43-36.gif
打开的登录网页是keycloak默认的界面,看教程可以定制,但是我没仔细看,这里先不写了,后面需要的时候再回来补充,这里刚开始一直提示“invalid redict_url"需要服务端修改如下:
image.png
这里需要注意,一旦用户登录成功,只要你没有logout,app就是一直登录的装填,因为他登录的时候是用系统浏览器进行的登录,应该session存在了系统浏览器里面(只是猜想没有验证,因为我删除之后,再安装,app还是登录状态)
app用restful登录:
但是用户的需求是不打开浏览器进行,需要进行restful登录:
https://www.keycloak.org/docs/latest/server_development/,最终在这里找到了restful相关的接口,app端登录变为如下:
const goLogin = useCallback(async () => {
const details: any = {
username: userName,
password: passWord,
grant_type: "password",
client_id: "candis",
};
let formBody = [];
for (var property in details) {
var encodedKey = encodeURIComponent(property);
var encodedValue = encodeURIComponent(details[property]);
formBody.push(encodedKey + "=" + encodedValue);
}
const result = await fetch(
"https://keycloak.dev-my.candis.io/auth/realms/candis/protocol/openid-connect/token",
{
body: formBody.join("&"),
headers: {
"content-type": "application/x-www-form-urlencoded",
},
method: "POST",
mode: "cors",
}
);
const resultJson = await result.json();
console.log(resultJson);
if (resultJson.access_token) {
NavigationService.navigate("AuthentificationScreen");
} else {
setVisible(true);
}
}, []);
注意需要:"content-type": "application/x-www-form-urlencoded",
服务器返回值:
{
"access_token": "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJWTUlIUG1tOTJPQ241aWtGTFBZdVd3djR2SVVZTzB3SFlqMXRsRkliZ25FIn0.eyJleHAiOjE2MjY4NDA3NjgsImlhdCI6MTYyNTYzMTE2OCwianRpIjoiNzllZThmOTYtMzBlNy00YjdkLTkyZDQtY2VhYTNjNDg4ODc1IiwiaXNzIjoiaHR0cHM6Ly9rZXljbG9hay5kZXYtbXkuY2FuZGlzLmlvL2F1dGgvcmVhbG1zL2NhbmRpcyIsImF1ZCI6ImFjY291bnQiLCJzdWIiOiI0ZjhlMGZhOS0xODc4LTRmNzctYmZkNy03OTc5MDU4ZDk0Y2MiLCJ0eXAiOiJCZWFyZXIiLCJhenAiOiJjYW5kaXMiLCJzZXNzaW9uX3N0YXRlIjoiZDRhNDRkMTYtNWZkZS00NjNmLWE3MWUtMjMwNTEzODQyODdiIiwiYWNyIjoiMSIsImFsbG93ZWQtb3JpZ2lucyI6WyJjYW5kaXMuaW8iLCIqIiwiaHR0cDovL2xvY2FsaG9zdDozMDAwIiwiaHR0cHM6Ly9jYW5kaXMuaW8iXSwicmVhbG1fYWNjZXNzIjp7InJvbGVzIjpbIm9mZmxpbmVfYWNjZXNzIiwidW1hX2F1dGhvcml6YXRpb24iXX0sInJlc291cmNlX2FjY2VzcyI6eyJhY2NvdW50Ijp7InJvbGVzIjpbIm1hbmFnZS1hY2NvdW50IiwibWFuYWdlLWFjY291bnQtbGlua3MiLCJ2aWV3LXByb2ZpbGUiXX19LCJzY29wZSI6Im9mZmxpbmVfYWNjZXNzIGVtYWlsIHByb2ZpbGUiLCJlbWFpbF92ZXJpZmllZCI6dHJ1ZSwibmFtZSI6IkppYW5sb25nIE5pZSIsInByZWZlcnJlZF91c2VybmFtZSI6Im5pZWppYW5sb25nMTFAZ21haWwuY29tIiwibG9jYWxlIjoiZW4iLCJnaXZlbl9uYW1lIjoiSmlhbmxvbmciLCJmYW1pbHlfbmFtZSI6Ik5pZSIsImVtYWlsIjoibmllamlhbmxvbmcxMUBnbWFpbC5jb20ifQ.GJc-b4eaPcHKWSfqzv1BXunY-D0LHF40SmFAYQJBp_sGgf_Cpx6_iIPDGc51psFK5hz7mwOU-VINi2RnOl37ylyHkZs1e9gkg_OQVkTOgHr8bY8-f1mByBfuBdAStjK904_Vr4L8_We7BCyPlkylYCJzaLsTafd58NAK-wcBPPhahQEr5-yXFczJxg43IU2RzH4xVMk2xu7Fnzf4fv5_EJ5LZIr4rHmVP3BFCXq0drd9hbIt0R7OMbyN-WbZbZEAzDijqnivcgsvL3mOyoePfT8iu3--zUnE2FLOPu_fU3jO85dPomIpz2TbQzMXqNsQQoLF6AEzDur9mUo4rizJ6Q",
"expires_in": 1209600,
"refresh_expires_in": 0,
"refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJjOTQ0YjI0NS1lOGFiLTRjN2EtYTg2MS1hZDY0MjAyZjA2NTMifQ.eyJpYXQiOjE2MjU2MzExNjgsImp0aSI6IjdkMGFiNTg4LTE3MDctNGZiYS04ZmVlLWQ3MTlkMDMyMmMwYiIsImlzcyI6Imh0dHBzOi8va2V5Y2xvYWsuZGV2LW15LmNhbmRpcy5pby9hdXRoL3JlYWxtcy9jYW5kaXMiLCJhdWQiOiJodHRwczovL2tleWNsb2FrLmRldi1teS5jYW5kaXMuaW8vYXV0aC9yZWFsbXMvY2FuZGlzIiwic3ViIjoiNGY4ZTBmYTktMTg3OC00Zjc3LWJmZDctNzk3OTA1OGQ5NGNjIiwidHlwIjoiT2ZmbGluZSIsImF6cCI6ImNhbmRpcyIsInNlc3Npb25fc3RhdGUiOiJkNGE0NGQxNi01ZmRlLTQ2M2YtYTcxZS0yMzA1MTM4NDI4N2IiLCJzY29wZSI6Im9mZmxpbmVfYWNjZXNzIGVtYWlsIHByb2ZpbGUifQ.xM3AaV2Synhfspo4-fU9djuHP5Po725hLE-vMFaESoE",
"token_type": "bearer",
"not-before-policy": 0,
"session_state": "d4a44d16-5fde-463f-a71e-23051384287b",
"scope": "offline_access email profile"
}
keycloak 可以再服务端很容易的和现有系统集成,从而无需担心用户认证问题。
网友评论