반응형

어플리케이션 개발에 무엇을 이용할지 고민하다 Flutter를 선택하게되었다. React Native도 아주 조금하다가. 결국 손을 떼버렸다......

선택이유는 그냥 Flutter를 해보고 싶었다. 


ReactNative 설치

1. 2018/11/11 - [Develop/React Native] - React Native 설치 Windows, Android Studio 사용하기.

2. 2018/11/11 - [Develop/React Native] - React Native expo를 이용한 설치 Windows, Android Studio (v31.0.0)



이 글은 

안드로이드 스튜디오로 하는 방법과 VSCODE로 Flutter 설치 및 실행하는 방법이다.


1.  https://flutter.io/docs/get-started/install/windows 이 주소로 들어가 SDK zip를 다운받는다.

2. flutter_console


2-1. 다운받았으면 위에 나와있는 것 처럼 C:\src\flutter 경로에 압축을 푼다. 위 설명에보면 C:\Program Fils에 하지 않는 이유가 권한을 요청하기 때문이라고 한다.

아래와 같이 압축을 풀었으면 위 설명대로 flutter_console.bat를 실행한다.




2-2. flutter_console에 늘 이렇게 폴더에 들어가서 bat를 클릭해서 실행하기 귀찮다 그러므로 path를 등록하여 간단하게 바로 cmd창을 통해 실행을 하자.

아래의 설명처럼 flutter\bin의 경로를 Path에 지정해주면된다.



내 PC 우측 클릭 -> 고급시스템설정 -> 환경변수 -> Path에 아래와 같이 추가한다.




이렇게 추가하였으면 이제 간단하게 cmd창을 열고 flutter_console을 실행할 수 있다.


3. cmd창 또는 flutter_console.bat를 통해 flutter이용에 필요한 리스트를 점검해보자.



콘솔창에 flutter doctor 라고 입력하면 아래와 같이 리스트가 나온다.

현재 안드로이드 스튜디오가 깔려있지 않기 때문에 [X]라고 나오고 설치되지 않았다고 나온다

필자는 현재 VS Code가 깔려있어서 저렇게 나온다.

그리고 device가연결된게 없다고 나온다.




4. https://developer.android.com/studio/ 옆의 경로로 들어가서 안드로이드 스튜디오를 설치한다. 


파일을 다운받고 Next를 누르고 일단 설치한다. (설치하는 것 자체는 어렵지 않음)


설치하였으면 이제 flutter를 추가해주어야 한다. 아래의 사진처럼 plugin에 들어간다



5. 접속하였으면 flutter라고 입력한다.

아래의 사진처럼 flutter라고 입력하면 Search in repositories라고 나오는 데 이것을 클릭하고

flutter를 Install한다. 

Install 하였으면 안드로이드 스튜디오를 재시작한다.




6. 안드로이드 스튜디오를 재시작 하였으면 아래의 사진처럼 Start a new Flutter project가 생성된다.

이것을 클릭한 후 프로젝트를 하나 생성한다.




7. 프로젝트를 생성하였으면 가상 DEVICE를 설치한다.

아래의 사진들 처럼 Tools -> AVD Manager -> Create Virtual Device 를 통해 AVD를 하나 생성한다
필자는 Nexus 5x를 생성하였다.




8. flutter doctor를 통해 점검해본다.

이제 안드로이드 스튜디오가 설치 되어있는 것을 확인할 수 있다.

그리고 To resolve this, run : flutter doctor --andorid-licenses 를 볼 수 있는데

말그대로 flutter doctor --andorid-licenses 를 cmd 창에 입력한 후 모두 yes하면 된다.



9. AVD를 실행한 뒤 flutter doctor를 실행한다.


AVD를 실행하면 아래와 같이 모두 완료되었다고 알려준다.




10. 마지막으로 run -> main.dart를 통해 실행해본다.




11. 이제 VSCODE로 한번 실행해보자

https://code.visualstudio.com/ 에 접속하여 VSCODE를 다운받는다.


12. 다운받고 실행하였으면 좌측 메뉴 맨 밑에 탭을 클릭하고 DART를 설치한다.




13. 설치하였다면

맨위 탭에 View -> Command Palette (ctrl + shift + p) 를 클릭 또는 단축키를 이용한 뒤

Flutter: New Project를 클릭하여 적절한 폴더에 프로젝트를 생성한다.



14. 안드로이드 스튜디오의 AVD매니저를 실행하고 Debug -> Start Without Debugging 을 통해 실행한 다음 확인한다.




이로써 안드로이드 스튜디오에서 flutter 작동하는 방법 및 VSCODE에서 flutter 작동하는 방법을 알아 보았다.


반응형
반응형



LocalDateTime 의 형식 때문에 Gson으로 JSON으로 변경시 아래의 사진 처럼 Data가 Deserialize 하게 나온다.



처음엔 Gson 때문인지 몰랐고 jackson-datatype-jsr310 이거 때문인 줄 알아, 정말 쌩고생을 했음에도 불구하고 안되다가

혹시나 해서 LocalDateTime 형식 때문에 Json으로 변경시 이상하게 되는가 싶어 확인했다가 정말로 Gson때문인 걸 알게되었다.

이유는 아마도 LocalDateTime 형식에서 2019-01-06T00:24:38 가운데 T 때문에 Gson에서 자동으로 위의 사진처럼 date와 time으로

나누어 주는 것 같다.



1. JPA를 사용할 것이고, DB의 날짜 형식은 TimeStamp를 사용한다. 일단 Converter를 만들어야 한다. Spring boot에서의 JPA는 2.1을 사용하기 때문에 JPA 2.1은 Java8에서의 LocalDateTime을 지원하지 않기 때문에 Converter를 만든다. 


Converter를 만드는 법은 아래와 같이 어노테이션을 추가하거나


@SpringBootApplication
@EntityScan(basePackageClasses = {Application.class, Jsr310JpaConverters.class} )
public class Application {

  public static void main(String[] args) {
    SpringApplication.run(Application.class, args);
  }
}


아래와 같이 직접 만든다.


import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

import javax.persistence.AttributeConverter;
import javax.persistence.Converter;

import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;

@Converter(autoApply = true)
public class DateConverter implements AttributeConverter<LocalDateTime, Timestamp> {
	@Override
	public Timestamp convertToDatabaseColumn(LocalDateTime locDateTime) {
		return (locDateTime == null ? null : Timestamp.valueOf(locDateTime));
	}

	@Override
	public LocalDateTime convertToEntityAttribute(Timestamp sqlTimestamp) {
		
		return (sqlTimestamp == null ? null : sqlTimestamp.toLocalDateTime());
	}
}


2. 만들었으면 데이터베이스를 통해 Date를 가져오는 것은 문제 없이 작동된다.

하지만 값을 찍어보면 Deserialize 하게 나온다. Gson을 사용하지 않고 순수하게 값만 가져올 경우는 이제

pom.xml에 아래의 maven을 추가한 뒤


       

			com.fasterxml.jackson.datatype
			jackson-datatype-jsr310
 

application.properties에 아래처럼 추가하면 Deserialize 하게 나오던 값이 serialize 나온다.

spring.jackson.serialization.write-dates-as-timestamps=false

하지만 우리가 할 것은 Gson을 통해 변경하는 것이기 때문에 위와 같이 하여도 아무런 변화를 느끼지 못할 것이다.


3. 이제 Gson을 통해 변경하기 위해 클래스를 생성한다.


import java.lang.reflect.Type;
import java.time.LocalDateTime;

import com.google.gson.JsonElement;
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;

public class GsonConfig implements JsonSerializer<localdatetime>{

	@Override
	public JsonElement serialize(LocalDateTime date, Type type, JsonSerializationContext json) {
		// TODO Auto-generated method stub
		return new JsonPrimitive(date.toString());
	}

}


그리고 이제 Gson을 사용시 아래처럼 사용한다.


Gson gson = new GsonBuilder().registerTypeAdapter(LocalDateTime.class, new GsonConfig()).create();
String jsonString = gson.toJson("변경할 값");

4. 이렇게 하면 2019-01-06T00:24:38 가운데 T 때문에 맨위의 사진처럼  Deserialize 나온 값이

 아래의 사진처럼  Serialize하게 나온다.


반응형
반응형

 

Node.js에서 google oauth 인증하는 방법이다. 

passport를 사용하는 방법이 있지만 passport는 사용해보니 무조건 session을 이용해야 했다.(아닐 수도 있음.)

이 글은 passport를 사용하지 않는 방법이다.

 

1.passport를 사용한 google oauth 인증

2019/03/11 - [Develop/Node.js] - [Node.js] google oatuh passport

 

 

 

프로젝트는 아래의 글을 사용했다. (순수 express 설치하는 글임)

2019/01/06 - [Develop/Node.js] - [Node.js] Express 설치(Windows)

 

1. googleapis 를 설치한다

npm install googleapis --save

2. google cloud console에서 .json파일을 받는다.

 

받은 파일을 아래와 같이 config 폴더에 넣어 google.json으로 변경한다.

 

 

반응형

 

3. server.js 파일에 아래와 같이 추가한다.

 

install 한 googleapis를 불러오고 .json 파일에서 client_id와 secret, redirect_uri를 불러온다.

const { google } = require('googleapis'); var googleClient = require('./config/google.json');  const googleConfig = {   clientId: googleClient.web.client_id,   clientSecret: googleClient.web.client_secret,   redirect: googleClient.web.redirect_uris[0] }; 

사용할 scopes를 입력하고, OAuth2.0에 실질적으로 연결할 정보들을 다시 연결한다. 

scope는 아래 API라이브러리에서 본인이 사용하고 싶은 api를 보고 가져오면된다.

여기서는 google api + 를 이용할 예정이다.

 

 

const scopes = [   'https://www.googleapis.com/auth/plus.me' ];   const oauth2Client = new google.auth.OAuth2(   googleConfig.clientId,   googleConfig.clientSecret,   googleConfig.redirect ); 

로그인 url을 받아오기 위한 정보를 입력한다. 

access_type에는 online과 offline이 있는데 offline으로 해야 제일 처음 로그인 했을 때 refresh_token을 받아온다.

(refresh_token은 항상 제일 처음 로그인할 때 가져온다 그러므로 다시 가져오고 싶으면 https://myaccount.google.com/permissions 에서 액세스된 어플리케이션을 해제해야 한다.)

 

scope는 위에 입력한 scope들을 가져온다. 지금처럼 scope하나만 가져올경우 

scope : 'https://www.googleapis.com/auth/plus.me' 바로 적어도 된다. 하지만 여러 scope를 가져올 경우 위에 처럼 배열을 하나 만들어

여러 scope들을 사용할 수 있다.

그리고 google+ api를 사용하기 위해 google+ api에 대한 정보를 입력한다.

const url = oauth2Client.generateAuthUrl({      access_type: 'offline',       scope: scopes });  function getGooglePlusApi(auth) {   return google.plus({ version: 'v1', auth }); } 

실질적으로 로그인해서 정보를 불러올 코드를 작성한다. 

간단하게 리프레시토큰, 액세스토큰, displayName과 id를 얻어와본다.

async function googleLogin(code) {   const { tokens } = await oauth2Client.getToken(code);   oauth2Client.setCredentials(tokens);   oauth2Client.on('tokens', (token) => {     if(tokens.refresh_token){       console.log("리프레시 토큰 :", tokens.refresh_token);     }     console.log("액세스 토큰:", tokens.access_token);   });   const plus = getGooglePlusApi(oauth2Client);   const res = await plus.people.get({ userId: 'me' });   console.log(`Hello ${res.data.displayName}! ${res.data.id}`);   return res.data.displayName; }

4. login할 주소와 로그인이 되었을 경우 실행될 callback 주소를 작성한다.

로그인할 주소는 아까 로그인 할 url 받아올 url변수의 정보를 redirect 시키고

callback 주소는 google.json의 redirect 주소를 적으면 된다.

그리고 로그인이 성공했을 경우 돌아올 redircet주소를 적는다. 

 

app.get('/login', function (req, res) {   res.redirect(url); });  app.get("/auth/google/callback", async function (req, res) {    const displayName = await googleLogin(req.query.code);   console.log(displayName);    res.redirect("http://localhost:3000"); });  

5. 실행한다.

 

 

localhost:3000/login 으로 들어간다.

 

 

 

localhost:3000/login 으로 들어가면 아까 url 을 통해 아래의 사진으로 연결된다.

 

이제 아이디를 쳐서 로그인하면 아까 입력한 scope에 따라 권한을 받게되고 이후 성공하면 redirect 시킨 home으로 돌아온다.

 

 

그리고 console을 확인해보면 현재 액세스토큰과 displayName, id가 나왔다.

리프레시토큰은 전에 로그인을 한번해서(시험 삼아 한번 해봄). 안나왔지만, 제일 처음 로그인을 했다면 리프레시토큰 또한 나올 것이다.

(리프레시토큰은 제일 처음 한번만 발급된다.)

 

 

6. 전체코드

 

 

var express = require('express'); var app = express();  const { google } = require('googleapis'); var googleClient = require('./config/google.json');  const googleConfig = {   clientId: googleClient.web.client_id,   clientSecret: googleClient.web.client_secret,   redirect: googleClient.web.redirect_uris[0] };  const scopes = [   'https://www.googleapis.com/auth/plus.me' ];  const oauth2Client = new google.auth.OAuth2(   googleConfig.clientId,   googleConfig.clientSecret,   googleConfig.redirect );  const url = oauth2Client.generateAuthUrl({    access_type: 'offline',    scope: scopes });  function getGooglePlusApi(auth) {   return google.plus({ version: 'v1', auth }); }  async function googleLogin(code) {   const { tokens } = await oauth2Client.getToken(code);   oauth2Client.setCredentials(tokens);   oauth2Client.on('tokens', (tokens) => {     if(tokens.refresh_token){       console.log("리프레시 토큰 :", tokens.refresh_token);     }     console.log("액세스 토큰:", tokens.access_token);   });   const plus = getGooglePlusApi(oauth2Client);   const res = await plus.people.get({ userId: 'me' });   console.log(`Hello ${res.data.displayName}! ${res.data.id}`);   return res.data.displayName; }  app.get('/login', function (req, res) {   res.redirect(url); });  app.get("/auth/google/callback", async function (req, res) {    const displayName = await googleLogin(req.query.code);   console.log(displayName);    res.redirect("http://localhost:3000"); });    app.get('/', function (req, res) {   res.send('Hello World!');   console.log("로그인 해서 홈으로 돌아옴");  });  app.listen(3000, function () {   console.log('Example app listening on port 3000!'); }); 

 

 

 

참고 : 

 

https://www.npmjs.com/package/googleapis

 

반응형

+ Recent posts