Spring Webflux에 구글 로그인을 달아보려고 했는데 생각보다 보게 되는 게 많았다. 워낙에 자바가 볼게 많은 거 같다.
세세한 사항도 많고 자동으로 되어 있는 부분도 많은데 고칠거 없으면 그냥 쓰면 되지만 수정하려면 모르고 하기도 애매하니 암튼 이제 스프링에 구글 로그인을 붙여 보려고 한다 잘되야 할 텐데.
Thymeleaf 수정 사항
Deprecated unwrapped fragment expression "header::header" found in template layout, line 24, col 6. Please use the complete syntax of fragment expressions instead ("~{header::header}"). The old, unwrapped syntax for fragment expressions will be removed in future versions of Thymeleaf.
<div th:replace="header::header"></div>
<div th:replace="~{header::header}"></div>
~{}로 감싸 주라는 경고가 자꾸 떠서 변경해 주었다
<div layout:fragment="header">
이 코드를 인식 못해서
<header layout:frament="header">
로 사용했었는데
<div th:fragment="header">
layout:frament 가 아니라 th:fragment였다
어떻게 저렇게 코딩하고 사용하였는지 신기할 따름이지만 정상적으로 작동했던 것도 신기하다.
firebase ui를 이용하기 위해 자바 스크립트 링크를 삽입해 줘야 하는데 다국어도 지원을 해준다 src 중간에 랭귀지 코드를 입력해 줘야 하는데 thymeleaf 표현식이 또 속을 썩였다.
<script src="https://www.gstatic.com/firebasejs/ui/6.0.2/firebase-ui-auth__{LANGUAGE_CODE}.js"></script>
<link type="text/css" rel="stylesheet" href="https://www.gstatic.com/firebasejs/ui/6.0.2/firebase-ui-auth.css" />
- Simple expressions: th:src 활용법
- Variable Expressions: ${...}
- Selection Variable Expressions: *{...}
- Message Expressions: #{...}
- Link URL Expressions: @{...}
- Fragment Expressions: ~{...}
심플 익스프레션 이라지만 나에겐 안 심플했다.
<img src="../../images/gtvglogo.png"
th:src="@{/images/gtvglogo.png}" th:alt-title="#{logo}" />
여태까지는 저런 식으로 사용을 해왔다 링크나 주소표현은 @{} 표현식으로 근데 거기에 랭귀지 코드를 변수에 들어 있는 것을 변환시켜 줘야 하니 엄청난 삽질을 했다 답은
<script th:src="${'https://www.gstatic.com/firebasejs/ui/6.0.2/firebase-ui-auth__'+ #locale.language + '.js'}"></script>
src를 th:src 변환한다고 해주고 ${} 변수 표현식으로 묶고 문자랑 변수랑 더해서 원하는 결과물을 얻어 냈다 저게 맞나 싶기도 하지만 일단 결과물은 성공적으로 나왔다.
Thymeleaf 정적 리소트 위치
JS 나 이미지 파일 등을 전에는 resource 밑에 static 폴더에 넣고 사용했었는데 기본위치가 바뀌었나 보다
staic 밑에 넣었더니 작동을 안 하고 assets 밑에 두니 잘 작동한다
<script th:src="@{/google/firebase-app-compat.js}"></script>
이널 식으로 th:src 태그와 @{} 표현식으로 사용하면 된다. 머 이리 변경된 게 많아 한 줄 한줄 다 걸리네.
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
th:lang="${#locale.language}"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
>
<head layout:fragment="head">
<title>Sample FirebaseUI App</title>
<script src="https://www.gstatic.com/firebasejs/9.13.0/firebase-app-compat.js"></script>
<script src="https://www.gstatic.com/firebasejs/9.13.0/firebase-auth-compat.js"></script>
<script th:src="${'https://www.gstatic.com/firebasejs/ui/6.0.2/firebase-ui-auth__'+ #locale.language + '.js'}"></script>
<link type="text/css" rel="stylesheet" href="https://www.gstatic.com/firebasejs/ui/6.0.2/firebase-ui-auth.css"/>
</head>
<body>
<div th:replace="~{header::header}"></div>
<h1>Welcome to My Awesome App</h1>
<div id="firebaseui-auth-container"></div>
</body>
<script type="module">
// Import the functions you need from the SDKs you need
import {initializeApp} from "https://www.gstatic.com/firebasejs/9.16.0/firebase-app.js";
import { getAuth } from "https://www.gstatic.com/firebasejs/9.16.0/firebase-auth.js";
import {getAnalytics} from "https://www.gstatic.com/firebasejs/9.16.0/firebase-analytics.js";
// TODO: Add SDKs for Firebase products that you want to use
// https://firebase.google.com/docs/web/setup#available-libraries
// Your web app's Firebase configuration
// For Firebase JS SDK v7.20.0 and later, measurementId is optional
const firebaseConfig = {
apiKey: "xxx",
authDomain: "xxx",
projectId: "xxx",
storageBucket: "xxx",
messagingSenderId: "xxx",
appId: "xxx",
measurementId: "xxx",
};
// Initialize Firebase
const app = initializeApp(firebaseConfig);
const auth = getAuth(app)
const analytics = getAnalytics(app);
// FirebaseUI config.
var uiConfig = {
signInSuccessUrl: '/signin/success',
signInOptions: [
// Leave the lines as is for the providers you want to offer your users.
firebase.auth.GoogleAuthProvider.PROVIDER_ID,
// firebase.auth.FacebookAuthProvider.PROVIDER_ID,
// firebase.auth.TwitterAuthProvider.PROVIDER_ID,
// firebase.auth.GithubAuthProvider.PROVIDER_ID,
// firebase.auth.EmailAuthProvider.PROVIDER_ID,
// firebase.auth.PhoneAuthProvider.PROVIDER_ID,
// firebaseui.auth.AnonymousAuthProvider.PROVIDER_ID
],
// tosUrl and privacyPolicyUrl accept either url string or a callback
// function.
// Terms of service url/callback.
tosUrl: '/',
// Privacy policy url/callback.
privacyPolicyUrl: function () {
window.location.assign('/');
}
};
// Initialize the FirebaseUI Widget using Firebase.
var ui = new firebaseui.auth.AuthUI(firebase.auth());
// The start method will wait until the DOM is loaded.
ui.start('#firebaseui-auth-container', uiConfig);
</script>
</html>
이렇게 하면 돼야 하는 안된다.
firebaseNamespaceCore.ts:102 Uncaught FirebaseError: Firebase: No Firebase App '[DEFAULT]' has been created - call Firebase App.initializeApp() (app-compat/no-app).
at o (firebaseNamespaceCore.ts:102:27)
at Object.e [as auth] (firebaseNamespaceCore.ts:153:31)
at signin:81:50
이런 에러 메시지와 함께 로그인 창이 뜨지 않는다... 플러터에서도 예제처럼 하면 먼가 한 줄 더 넣어 주지 않으면 에러가 떴던 거 같은데 왜 공식 문서를 보고 그래도 했는데도 안 되는 것일까? 나만 안 되는 건 아닐 텐데 자료가 별로 없네.. module를 써보긴 또 처음이네 계속 먼가 나오고 변하고 한다.
Web에서 javascript CDN 사용하여 firebase google login 창 띄우기
공홈 샘플 문서에서 본 그대로 코드를 작성하였는데 작동하지 않아서 원인을 한참 찾았다 혹시 자바스크립트 로딩이 오래 걸려서 안되나 하는 마음에 딜레이도 주고 다 테스트해보니 안되다 소스를 가만히 뜯어보니
var ui = new firebaseui.auth.AuthUI(firebase.auth()); -> 요 부분에서 auth를 넘겨주는데 나는 이미 만들어진 객체에서 참조해서 쓰나 했더니 위쪽에서 만들어 놓은 const auth = getAuth(app) auth를 주입해 줬더니 아래와 같이
Sign in with Google 버튼이 떴다. 띄우고 나서도 먼가 설정해 줘야 하는지 또 막히는데 그건 또 풀어 봐야겠다
웹에서 구글 로그인 달아 본건 처음이라 맨날 jdbc에 아이디 비번을 이용한 것만 만들어서 썼더니 다 새롭다.
그리고 jwt 받아서 처리해주고 필터 달고 하는 것도 해봐야 해서 앞으로도 시간이 많이 걸릴 거 같다 그래도 한번 하고 나면 빨라지니 끝까지 해보겠다.
spring 웹 페이지에서 자바스크립트로 구글 로그인창 띄우기
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
th:lang="${#locale.language}"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
>
<head layout:fragment="head">
<title>Sample FirebaseUI App</title>
<script src="https://www.gstatic.com/firebasejs/9.13.0/firebase-app-compat.js"></script>
<script src="https://www.gstatic.com/firebasejs/9.13.0/firebase-auth-compat.js"></script>
<script th:src="${'https://www.gstatic.com/firebasejs/ui/6.0.2/firebase-ui-auth__'+ #locale.language + '.js'}"></script>
<link type="text/css" rel="stylesheet" href="https://www.gstatic.com/firebasejs/ui/6.0.2/firebase-ui-auth.css"/>
</head>
<body>
<div th:replace="~{header::header}"></div>
<h1>Welcome to My Awesome App</h1>
<div id="firebaseui-auth-container"></div>
</body>
<script type="module">
// Import the functions you need from the SDKs you need
import {initializeApp} from "https://www.gstatic.com/firebasejs/9.16.0/firebase-app.js";
import {getAuth} from "https://www.gstatic.com/firebasejs/9.16.0/firebase-auth.js";
import {getAnalytics} from "https://www.gstatic.com/firebasejs/9.16.0/firebase-analytics.js";
// TODO: Add SDKs for Firebase products that you want to use
// https://firebase.google.com/docs/web/setup#available-libraries
// Your web app's Firebase configuration
// For Firebase JS SDK v7.20.0 and later, measurementId is optional
const firebaseConfig = {
apiKey: "xxx",
authDomain: "xxx",
projectId: "xxx",
storageBucket: "xxx",
messagingSenderId: "xxx",
appId: "xxx",
measurementId: "xxx"
};
// Initialize Firebase
const app = initializeApp(firebaseConfig);
const auth = getAuth(app)
const analytics = getAnalytics(app);
// FirebaseUI config.
var uiConfig = {
signInSuccessUrl: '/signin/success',
signInOptions: [
// Leave the lines as is for the providers you want to offer your users.
firebase.auth.GoogleAuthProvider.PROVIDER_ID,
// firebase.auth.FacebookAuthProvider.PROVIDER_ID,
// firebase.auth.TwitterAuthProvider.PROVIDER_ID,
// firebase.auth.GithubAuthProvider.PROVIDER_ID,
// firebase.auth.EmailAuthProvider.PROVIDER_ID,
// firebase.auth.PhoneAuthProvider.PROVIDER_ID,
// firebaseui.auth.AnonymousAuthProvider.PROVIDER_ID
],
// tosUrl and privacyPolicyUrl accept either url string or a callback
// function.
// Terms of service url/callback.
tosUrl: '/',
// Privacy policy url/callback.
privacyPolicyUrl: function () {
window.location.assign('/');
}
};
// Initialize the FirebaseUI Widget using Firebase.
var ui = new firebaseui.auth.AuthUI(auth);
ui.start('#firebaseui-auth-container', uiConfig);
</script>
</html>
No Firebase App '[DEFAULT]' has been created - call Firebase App.initializeApp()
이 에러로 비슷한 문제를 찾는 글들이 많았는데 나 같은 사람이 없진 않은 거 같다.
저의 시행착오는 상단에서 만들어 놓은 auth를 주입해 주면 되는 것이었는데. 문서에 있는 대로 파이어베이스에서 만든 앱을 찾아서 주입한다는 식으로 하니 안 되는 거였다 일단 문제 하나는 해결한 거 같으니 다음 문제를 해결해 보러 가겠다.
이전 글
https://devkimchi.tistory.com/70
'개발 > 스프링 FIreBase Neo4j' 카테고리의 다른 글
SPRING WEBFLUX OAUTH 2.0 구글 로그인 후 넘어 오는 값(CODE) 방황기 (0) | 2023.01.29 |
---|---|
firebase login Sign-in method, web ui 설정, google 로그인 제공 업체 추가 (0) | 2023.01.26 |
Firebase, WebFlux Security, Spring 기본 설정드, 어노테이션 등 (0) | 2023.01.25 |
IntellJ 필수 플러그인, Spring webFlux firebase admin (0) | 2023.01.23 |
webflux Thymeleaf3.1 template, Layout 변경된 부분 마이그레이션 (feat LiveReload++) (0) | 2023.01.23 |